Apache Mina: Get local port to which remote client connected - java

If I have a server listening on ports 80 and 8080 as configured below, how would I be able to identify which local port a client connected to when i get a message?
acceptor = new NioSocketAcceptor();
acceptor.setHandler(new MyConnectionHandler());
Set<SocketAddress> addresses = new HashSet<SocketAddress>();
addresses.add(new InetSocketAddress(host, 80));
addresses.add(new InetSocketAddress(host, 8080));
acceptor.bind(addresses);
The handler's messageReceived I want to know which local port the client connected to, not the client's remote port.
#Override
public void messageReceived(IoSession session, Object message) throws Exception {
log.info("Incomming: {}", session.getRemoteAddress().toString());
Which method should I use to access the port which should be 80 or 8080? The log statement would print something like this:
Incomming: /219.182.172.12:37921

session.getLocalAddress()

Related

How to dynamically receive udp message from the source port using netty?

I need to communicate with a server using udp message like this. For example, my client ip is 192.168.86.50 and the server is listening to port 7777 on address 127.0.0.1
UDP message from my client to server: 192.168.86.50:54321 --> 127.0.0.1:7777
The client will reply with a UDP message like this: 127.0.0.1:7777 --> 192.168.86.50:54321
How do I write Netty to dynamically listening to a source port of a udp message? The source port is dynamically generate from the OS.
Thanks,
You can specify the Source (local) address while connecting.
Here is a snippet:
Bootstrap bootstrap = new Bootstrap()
.group(new NioEventLoopGroup(1))
.channel(NioDatagramChannel.class)
.handler(new Handler());
SocketAddress serverAddress = new InetSocketAddress("127.0.0.1", 7777);
SocketAddress localAddress = new InetSocketAddress("192.168.86.50", 5555);
bootstrap.connect(serverAddress, localAddress);

How to get local address of a DatagramSocket (UDP) in Java

I'm implementing a DNS server with DatagramSocket (UDP) in Java and the code looks like:
try (DatagramSocket socket = new DatagramSocket(new InetSocketAddress("0.0.0.0", 53))) {
DatagramPacket request = ... // Init Packet
socket.receive(request);
... // Parse request, Resolve, then Generate reesponse
socket.send(response);
}
It works fine on my PC and most servers (including aws, linode, etc), but does not work well on a server with double ethernet adapter.
This server has a network config:
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 192.168.1.204
netmask 255.255.255.0
auto eth1
iface eth1 inet static
address 192.168.1.207
netmask 255.255.255.0
When I test this DNS, I get:
# nslookup
> server 192.168.1.207
Default server: 192.168.1.207
Address: 192.168.1.207#53
> info.dev.
;; reply from unexpected source: 192.168.1.204#53, expected 192.168.1.207#53
;; reply from unexpected source: 192.168.1.204#53, expected 192.168.1.207#53
;; reply from unexpected source: 192.168.1.204#53, expected 192.168.1.207#53
;; connection timed out; no servers could be reached
>
It seems to receive a packet from eth1 (192.168.1.207) but send to eth0 (192.168.1.204). And my code does not know which interface the packet is received from.
try (DatagramSocket socket = new DatagramSocket(new InetSocketAddress("0.0.0.0", 53))) {
...
socket.receive(request); // local socket address not known :-(
...
socket.send(response); // local socket address not known :-(
}
Socket (TCP) can do this but I do not know whether DatagramSocket (UDP) can do so.
UPDATE-1:
bind one interface instead of 0.0.0.0, it works fine.
UPDATE-2:
Socket (TCP) can get both local and remote address:
try (ServerSocket server = new ServerSocket(23)) {
try (Socket socket = server.accept()) {
System.out.println(socket.getLocalSocketAddress());
System.out.println(socket.getRemoteSocketAddress());
}
}
The local address of that DatagramSocket is 0.0.0.0:53. The one you specified when you constructed it. Which interface it uses to reply on is determined by the static IP routing tables. Not by this code. And getting the local address of the DatagramSocket, or even the target address of the datagram (which you can get in C but not Java), wouldn't help you to solve this problem, if it is a problem.
my code does not know which interface the packet is received from.
Correct. It doesn't care. It is listening at all IP addresses. You told it to do that. It only cares about the remote address, which you haven't shown but have clearly got correct.
try (DatagramSocket socket = new DatagramSocket(new InetSocketAddress("0.0.0.0", 53))) {
I don't know why you've posted this twice.
What you have here is a static IP routing issue. Not a programming problem.

ID for local client using sockets in java

I want get unique ID for my client connected by a server. I have many clients, but, each one want has one different ID. An close solution is similar to this:
Socket cliente = servidor.accept();
System.out.println("New connection with" +
cliente.getInetAddress().getHostAddress());
String addr = servidor.getLocalSocketAddress().toString();
ThreadServidor ts = new ThreadServidor(addr, cliente);
ts.start();
The clients have the same code to connect:
Socket conexao = new Socket("127.0.0.1", 12345);
I need the information of the own client ip and port connected too.
Thanks
The following methods can be called on your socket cliente to get the local and remote IP addresses and the local and remote ports.
getLocalAddress()
getLocalPort()
getInetAddress() // gets the remote address
getPort() // gets the remote port
The combination of all that information is unique.
More info at the Javadoc:
http://docs.oracle.com/javase/7/docs/api/java/net/Socket.html
Just use Socket.getRemoteSocketAddress(). It embodies the remote host:port, which is all you need at the server end.

Netty: getting remote ip address in messageReceived

In my class (extends SimpleChannelHandler) I'm trying to get the ip where the message was originally sent from.
#Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent ev) throws Exception {
String host = ((InetSocketAddress)ctx.getChannel().getRemoteAddress()).getAddress().getHostAddress();
int port = ((InetSocketAddress)ctx.getChannel().getRemoteAddress()).getPort();
LOG.debug(String.format("host:%s port:%d", host, port));
..
This prints ip 10.0.0.1 (gateway), instead of the correct client address (10.52.45.4).
Is there any way to get the ip i'm trying to or could there be something wrong with the network configuration ?
I guess you see the gateway ip because the gateway does some kind of NAT. If so, the only chance you have is to include the source-ip address in your protocol and extract it from there.
Ip addresses starting with 10.0.0 are internal, you are probably connecting it to something on the same WiFi router. To get the 10.52.45.4 ip, you have to connect outside of your router. (don't forget to port forward)

Netty is giving me a wrong port using TCP

I'm using Netty with Java trying to configure a TCP client. Everything is working so far, except that I'm connecting on port 1050 but when I call messageEvent.getRemoteAddress() on messageReceived() method of the handler, I'm getting the port 1500. I changed the port to 1049 but I'm still receiving 1500. This is Netty's problem or can it be the server's problem?
My hardware setup here is: this netty client running on a Java server, and several access control equipments spread through the area here. The equipments act as tcp servers and the netty as the client, that process everything the server sends and just reply to them.
The tcp server initialization is this:
private ChannelFactory fabrica;
private ServerBootstrap bootstrap;
public void iniciarServidorTCP() {
fabrica = new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
bootstrap = new ServerBootstrap(fabrica);
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
#Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("decoderDeMensagem", new MensagemDecoderTCP());
pipeline.addLast("handlerGerente", new GerenteTCP());
pipeline.addLast("encoder de mensagem", new MensagemEncoderTCP());
return pipeline;
}
});
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.reuseAddress", true);
bootstrap.bind(new InetSocketAddress(1050));
}
Any idea why I'm getting 1500 instead of 1050? Could it be a problem with the equipment?
Every TCP connection has a source port and a destination port. When you connect to a server, the server sees the destination port as its well-known address. The client picks the source port. On either end, getting the "remote address" gets the other side's address. So when you call get remote address on the server, you get the client's address, not the server's.
Imagine you have a server with one IP address and one well-known port. Now, say you have a client machine with one IP address. If it make's four connections to the server, how can either end tell those connections apart? The answer is that the client port is different.

Categories

Resources