The title may sound a bit odd but I wanted to keep the title short.
So I have here a Socket which connects to some server for testing purpose.
Now when I get the IP from the client socket (server side) it will give me one IP (external one).
But I have another IPv4 dedicated IP, can I use that as source?
If you want a Socket to originate on a particular IP/interface, you should be able to bind() it to the appropriate address before issuing the connect().
Related
I'm bit new to networking in java.
I fall into in a situation where I need to create a server socket which will listen on only selected IPs from all the available IPs in the machine.
I have 8 vNICs (interfaces) named from eth0 to eth7 each has its own IP. My server socket should listen only on eth4, eth5, eth6 & eth7.
At the moment I could see an option to listen on a particular IP or any available IPs in a machine. But my requirement is not ANY but only MULTIPLE IPs.
Also, I could see a solution where multiple sockets can be created as one for each IP. Total four sockets in my case.
Is there a better elegant solution?
You can't. You can listen on one IP address, or all of them. Nothing else.
You will have to create a listening socket per IP address.
Goal
I'm making a chat application for android and am currently testing with 2 phones which must eventually work for a few thousand users.
Problem
I get a ConnectionException saying "Connection refused" whenever the 2 phones try connecting to each other via sockets.
Current Design
Each phone starts a ServerSocket, calls the accept() method waiting for some Socket to connect to, and whichever phone sends a message first will create a client Socket. I'm certain the IP addresses I'm using are correct (they're actually both using the same external IP).
I believe the problem is with the ports. I generate a port number at random, and if it's free to use, I say ServerSocket s = new ServerSocket( randomPortNumber ).
What I think is the source of the problem
What I think is the problem is this port number is one sitting behind an NAT router. So when a Socket tries to connect to the ServerSocket using something like Socket socket = new Socket( ip, serverSocketRandomPortNumber ), it will try to connect to the NAT router and feed it this port number which won't work since the router itself is not listening on this port, but the phone behind the router is.
Questions and thoughts
My question is, how do I deal with this problem?
Do I have to change my design?
If I must, an alternative design I'm thinking of is using a single ServerSocket on a web host and use it to redirect messages sent from client sockets to other client sockets.
I'd be implementing the server-side in php referencing something along these lines:
http://php.net/manual/en/sockets.examples.php
And I would still use Java for the client-side.
Since one of the phones is behind a NAT router, nothing can initiate a connection to it unless port forwarding (or some other techniques) is enabled on the router.
The usual way a chat application is implemented is, there is a common server that all clients will connect to.
You don't have to write your own chat server (unless you really want to). I suggest using the XMPP protocol. A list of already made servers here. On the client side (Android), you can find libraries you can use here.
I am working with a Java desktop server and multiple Android clients connected to it. on the server side I need to identify which client has sent me a message by sockets TCP/IP and send a response only to that one client and not the others.
I will store all the sockets of clients in an ArrayList.
first here are two ways that I tried that don't work;
-- the IP address of the client, get this by calling socket.getLocalSocketAddress() in the client and socket.getRemoteSocketAddress() in the server, but they never match. for example i got in the client XXX.XXX.11.17 and in the server XXX.XXX.0.13, they are supposed to be the same for the same connection.
-- the port number, get this by calling getLocalPort() in the client and getPort() in the server, yes this works perfectly and the numbers match so I can use this, HOWEVER there is a possibility that the randomly selected port numbers on two different clients could be the same. not likely but possible. so that means there is no guarentee that they are unique.
what is the alternative that I can use that will work?
I need to identify which client has sent me a message by sockets TCP/IP and send a response only to that one client and not the others.
Send it back down the same socket you received the request from.
If you need a permanent identified for the client, you can use the result of Socket.getRemoteAddress().
getLocalSocketAddress() in the client and getRemoteSocketAddress() in the server [...] are supposed to be the same for the same connection.
No, because you don't know what's in between. Most mobile providers use proxies, NAT and so on. The mobile device thinks it's on a LAN (10.0.0.x or 192.168.x.x addresses) which the provider provides. It's even possible for multiple clients to have the same remote address (as seen from your server).
That being said, you can uniquely identify a client in your server application by the remote IP address and port combined together, given the server listens on one IP, port and protocol. This information is available from socket.getRemoteSocketAddress(), where the returned InetSocketAddress (in case of an internet socket) contains both the remote IP and port (getAddress() and getPort() respectively).
But as indicated by the other answer, you don't really need a way to identify a client. A network client is identified by the socket you receive data on (a socket is an exclusive connection between two nodes), so just send the data back to the socket that you received the request on.
If you do need more bookkeeping data about the connected client, wrap the client socket in a wrapper class that contains additional information.
I've a server (Java) and a number of clients (c++), connected by sockets.
I would like to set the ports automatically.
Assuming the IP is already known.
In the Java side I can make :
ServerSocket s = new ServerSocket(0);
So now I've a random free port on the server.
How can I know in the C++ side, what port is the server listening to?
I think is not possible, if you want establish a connection with a server, you must know in which port is the server listening, there are programs like nmap that shows you a list of opened ports in a server, but a server can have many opened ports at the same time and then, How do you know what is the port opened by your server? and in any case, is too slow and inefficient to call external tool, read and parse its output. For what reason do you need a random port service?
Other option can be get the opened socket in the server side calling to s.getLocalPort() and send it via UDP for any listening node in the network with broadcasting, and re-program the client side to listen in broadcast and when it receives a message, check if it is a port number and connect to the server using that port.
You can't, not reliably. In IP, a machine is identified by an address. A server (ie, a service) is identified by an address and a port. You clients need some form of "known service" that they can connect to.
If you, for whatever reason, absolutely want to have dynamic listening port, you could combine it with a "locator" service on a known port. For instance, have a web service/servlet on the standard http port (80). Your clients connect to the "locator" service (always on port 80) and asks which port your application is currently listening on. This is a not entirely uncommon pattern. RMI works is a similar way where you have a registry on a known port. Clients connect to the registry and asks for the location of RMI endpoints.
Well, i am at new at Socket programming in java. I tried to implement a simple socket program to send the message with 127.0.0.1:4242 as localhost. But i want to send message to specific IP. How can i achieve that? Will it be possible to send message to my own IP as client-server running simultaneously?
An endpoint in socket communications is an endpoint. Anything you can do using 127.0.0.1 can be done using that machines ip address. See here for more details.
Every IP datagram has a source address and a destination address in the IP header, plus a transport protocol number, which is for majority of Internet traffic is either TCP or UDP. Then the header for that transport protocol lists source and destination port numbers.
So here you have it - sending, or better said "client", application gets assigned source address and port, usually automatically - address determined by the local routing table, port number assigned out of range of ephemeral ports, while "server" application listens on a well known port bound to an address at a particular machine. This tuple (source IP, source port, destination IP, destination port) is enough for the datagram to get from here to there.
127.0.0.1, and actually all the addresses in the range 127/8, are reserved for the loopback, a virtual local interface, i.e. it's the way to say "no matter what my real address is, or even if I don't have one, connect to this machine I'm at right now".
Read up on the TCP/IP suite of protocols - it's a fairly simple concept (with ton of interesting details, of cource).