java client-server app - unable to create multiple clients - java

I am creating a multi threaded app, where server should handle multiple client requests simultaneously. Further, a client should communicate with other clients. The server will hold the port address of various clients and so each client must contact the server in order to know the port address of its peers.
My understanding about the programs:
client.java ( has a socket and a server socket)
socket - used for talking to the server in order to register its serversocket no, which will help other peers to identify. (Note: unlike server socket, where we might have to mentiond the port at the time of creation, socket # is uniquely assigned by the OS and so we don't need to worry about this.)
serversocket - used to talk to other peers and this number should be known by other peers.
server.java
serversocket - used for communicating with various clients
Now, I have two programs server.java and client.java. Of course, I will run client.java more than once in order to have multiple clients. Here are my questions:
will my client.java have two ports? one socket to talk to the server and one server socket to listen to other clients?
if so, should I pass the port no as a parameter to client.java so that it can be used as a unique server socket # for each client instance?
Please help me out!

yes you can pass them as runtime args or even better let the server decide it for you that way you wont have to worry about assigning unique port numbers.
Also i believe you will have to pass the client port and ip for clients to talk to each other, unless all your clients will be on the same machine.

Related

what to use for identifying between clients that connect to a server? Java, Android, Sockets

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.

Why Java ServerSocket accept() returns a socket with the same port as ServerSocket?

In the server side, i use this code :
ServerSocket server = new ServerSocket(1234);
Socket server_socket = server.accept();
I found the server is listening on port 1234.
When one or more client sockets are connected, they are all using the same port 1234 !
That is really confusing :
I remember that multi sockets can't use the same port, isn't it right ? Thanks.
A TCP connection is identified by four numbers:
client (or peer 1) IP
server (or peer 2) IP
client port
server port
A typical TCP connection is open as follows:
The client IP is given by the client's ISP or NAT.
The server IP is given by the user or looked up in a DNS.
The client chooses a port arbitrarily from the unassigned range (while avoiding duplicate quadruples)
The server port is given by the protocol or explicitly.
The port that you specify in the ServerSocket is the one the clients connect to. It's nothing more than a port number that the OS knows that belongs to your application and an object that passes the events from the OS to your application.
The ServerSocket#accept method returns a Socket. A Socket is an object that wraps a single TCP connection. That is, the client IP, the server IP, the client TCP port and the server TCP port (and some methods to pass the associated data around)
The first TCP packet that the client sends must contain the server port that your app listens on, otherwise the operating system wouldn't know what application the connection belongs to.
Further on, there is no incentive to switch the server TCP port to another number. It doesn't help the server machine OR the client machine, it needs some overhead to perform (you need to send the new and the old TCP port together), and there's additional overhead, since the server OS can no longer identify the application by a single port - it needs to associate the application with all server ports it uses (the clients still needs to do it, but a typical client has less connections than a typical server)
What you see is
two inbound connections, belonging to the server (local port:1234). Each has its own Socket in the server application.
two outbound connections, belonging to the client (remote port:1234). Each has its own Socket in the client application.
one listening connection, belonging to the server. This corresponds to the single ServerSocket that accepts connections.
Since they are loopback connections, you can see both endpoints mixed together on a single machine. You can also see two distinct client ports (52506 and 52511), both on the local side and on the remote side.

Multiple java socket connections

I have created this game bot where it connects to the game, and starts playing.
My problem is that i can't start more than one of these as the other then won't work.
Is is possible that if i run 2 instances of the same program the sockets are interfering with each other ? After all, they do connect to the same IP with the same port ?
And sometimes after i close(just closing cmd) the program is unable to connect again. Is that cause i didn't close the connections right ?.
I hope this is enough else i'll just have to post my source code
Best regards.
It's possible to connect to the same socket/port several times. Actually a socket is a double peer: {client ip/ client port}{server ip/server port}. When you connect to a server, your client port is assigned dynamically. You will have a new and different client port per client. So it should work unless the server side forbid it.
You should have a server that listens for multiple connections. A server is bound to a port and once that port is in use another application cannot use it. So for the server just have one instance. Multiple clients can connect to this IP/Port as long as the Server accepts multiple connections.
If a client connects to the server and the other clients stop working this may be because the server does not support multiple clients. To do this you need to use multi threading in the server. The server should accept a client socket and create a new instance of a client with it's own StreamReader/Writer objects.
http://tutorials.jenkov.com/java-multithreaded-servers/multithreaded-server.html
if you are working with a specific TCP port, then there is a close-wait period that this port cannot be claimed temporariliy for some time. also multiple programs cannot listen the same TCP port. Use threads.

Server UDP and port binding

I am writing this game in Java and have problems with networking architecture.
I decided I will UDP packets. I am just at the beginning, but the problem I am facing is that it seems to be that server have to respond from exactly same IP/Port to client (which is behind router which uses NAT) as client connected that server.
For example I have client A behind router. Client A has IP (local) 192.168.8.100 and it connects server B from port 1234. Server is on 11.11.11.11:2345.
When client A connects to server B it uses 192.168.8.100:1234 but router converts that to (for example) 22.22.22.22:6789.
Now, when server wants to send packets to that client it has to be from 11.11.11.11:2345.
I would like to send data from another port like 11.11.11.11:2222, but this does not seem to work, at least not with my router.
I want to use different port because I want to have two threads one for listening and one for sending data, and each thread would have it's own DatagramSocket. But, as i said once client A connects to server on port 2345, I can not send data from port 2222.
Does anyone know how is this handled? I am doing it in Java, but it's not really a language specific problem.
UPDATE
After #Perception commented I have some more questions regarding his comments:
OK, so if I understand this correctly, if I have server which is hosting 1000 games, each with 2 players, all sending/receiving will have to be done through the same DatagramSocket.
As I understand DatagramSocket is thread safe so I guess I can have one thread doing:
datagramSocket.receive();
while at the same time second thread is doing
datagramSocket.send(.....);
Correct?
Also, two threads can send data at the same time through the same DatagramSocket? Is sending in any way serialized, meaning that second send() starts only after previous send() is finished or is data being sent at the same time?
gorann, I'm not sure if I'm understanding you correctly, but it sounds like you're trying to control the port on which the server communicates with the client. There's no way to control this, and for good reasons.
This is one of the trickier differences between TCP and UDP.
When a new TCP session is initiated, the server side call to accept() gives you a new socket and the OS handles multiplexing the various sessions for you. With UDP, you need to handle the multiplexing yourself. But you need to do so in a way that works with NATs and other firewalls.
The way NAT works is that when it sees an outgoing packet, it creates a temporary rule allow packets to return along the same port pair. Data returning from a port that the client has not yet sent to will likely be blocked.
This gives you two choices:
You could do all of your communication through a single port. This is not a bad option, it just means that you need a way to identify client sessions and route them to the appropriate thread.
You could create a separate port and instruct the client to send to that one instead. Have the server listen on a fixed port. The client sends a message to there, the server then sets up a new session port and sends that number back to the client using the server's listen port. The client then sends a message to the session port, which causes the NAT to open up that port and allow return traffic. Now the client and server thread have their own private port pair.
Option 1 is a bit more work because it requires data to be exchanged between threads, but it scales up better. Option 1 is easier and more CPU efficient because each session thread can be independent, but there are a finite number of ports available.
Either way, I recommend that you have the client include a semi-unique session id in each packet so that the server has more than just the client address and port number to verify who belongs to each session.

C++/Java Sockets automatic Port allocation

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.

Categories