I'm working on a ServerSocket with java, and I would like to know, upon a client connecting, is it possible to send the Client/Socket to another ServerSocket. For example a client connects to 123.41.67.817(Just a random IP) and upon connection, the client gets sent straight to for example 124.51.85.147(Another Random IP) with a port of course. So a little Map of what would happen.
ServerSocket(Listening for Connections)
Client ---> ServerSocket(Client connects)
ServerSocket -> Client(Server says: Hello, I am going to send you to 124.51.85.147)
Client -> ServerSocket(Client Says: OK!)
Client ---> ServerSocket(124.51.85.147)(Client gets sent to a different server Socket)
ServerSocket(124.51.85.147) -> Client(Server2 says: Welcome!) and then the client stays on Server2(124.51.85.147)
Is this possible in any way. Sorry for the long question.
Is this possible in any way.
No.
At the most basic level, a TCP/IP connection is a conversation between a pair of IP addresses. There is no provision in the TCP/IP protocol for changing one of the two IP addresses in mid conversation.
Even if it were possible at the Java level to (somehow) serialize the Socket object and send it to another program (local or remote), it would not be possible to change the IP addresses for the underlying conversation; see above.
Historical footnote: A long time ago (1980's) in a country far away (Cambridge UK) there was a network (The Cambridge Ring) whose stream protocol (BSP) implemented an operation known as "replug". If you had BSP connection between A & B and another between B & C, then B could replug the connections so that A talked directly to C. Reference: "The Cambridge Distributed Computer System" by R.M. Needham & A.J Herbert (Annex C).
I've never seen a replug operation elsewhere. Indeed, if you think about it, it requires a complicated 3-way handshake to implement a replug-like operation reliably. In the BSP case, they didn't do that ... at least according to the description in Needham & Herbert.
Related
We have an java client-server RMI application. The client performs a call by:
public interface MyRemoteInterface extends java.rmi.Remote {
public byte[] action(byte[] b}
public static Remote lookUp(String ip, int port, String alias) {
return LocateRegistry.getRegistry(ip, port).lookup(alias)
}
serverImpl = (MyRemoteInterface)lookUp(ip, rmpiport, alias);
serverImpl.action(requestBytes);
..
It a classic rmi client-server appl. When the remote server receives the request (call) it performs some process P, which takes a time T and then returns. The problem is, suppose we have two clients C1 and C2, respectively, each are identical (same OS, same Java, no firewall, no antivirus etc). The difference of C1 and C2 is they are in different networks, different ISP provides etc. For example they are two users connecting from their home and use different service providers, modems and connecting to the centralized server S.
When the process P takes 4 minutes, there is no problem, both client receive the response. But if the process time takes for example 10 minutes, C2 receives no response without any exceptions on server or client side.
Question: What can be reason of this difference? How can the network architecture can effect the behaviour of rmi connection? Can we overcome this problem by setting some timeout parameters or jvm-parameters? We do not get any timeout exceptions on client or server. Simply one of the clients does not receive any response if the process time becomes longer.
Simply one of the clients does not receive any response if the process time becomes longer.
In our (enterprise) network we had some policy in force to close connections which were not active for long time. So there may be differences. Though the client should get a proper exception. For better answer you may gather more exact information on the network level (e. g. tcpdump)
But if the process time takes for example 10 minutes
I'm not really fond of long-running processes when executing remotely (regardless of the protocol). Mainly to prevent issues like the one in your question.
You may use some asynchronous processing, like a method to start a server process and then have the client to check for status/results.
So i am quite new to Sockets and I have to create a Server-Client-App for school.
I expect a client to request something from the server multiple times during his runtime.
I am uncertain wether I should make a new java.net.Socket for every Request I get (Client opens new socket every time and Java Serversocket accepts)
or use a single socket and keep that during the client's runtime.
That strongly depends on how frequently the socket is used.
E.g. if you know that the client will send a request to the server every 50 milliseconds it would be easier to just keep the socket opened.
But if you know the client will only request information from the socket every 5 minutes it's probably better to close the connection and create a new one when needed. Same if you don't know when the next request will be created.
Creating a new Socket on server-side is not very expensive, so it's probably better to just close the connection if it's not used very frequently.
An exception could be a special socket, that needs authentifications or other expensive stuff on creation, but that's probably not the case in a school project.
So in general: It depends on the usage of the socket, but if you're unshure whether it's used very frequently or not better close it and open it again when needed.
Related to this question:
Maximum number of socket in java
If you're worried about exceeding the maximum number of sockets that can be opened (I imagine this is highly unlikely in your case) you can create a work-around where you use TCP to initially establish the connection, send the client a UID (Unique Identifier, a 64-bit unsigned long long type should be sufficient) and then close the TCP connection. Fill and maintain a structure (or Class object in your case) detailing the connection details (IP address, Unique Identifier code) and then wait on arriving packets sent via UDP (User Datagram Protocol, an alternative to TCP). If you decide to use UDP, be aware that you'll need to implement a means of reordering packets in order to reconstruct a byte-stream (serialisation) and a mechanism for resending data packets if somehow they do not arrive (packet loss recovery).
Sounds worse than it is. I'll repeat though, don't bother yourself with these intricacies if you're not worried about exceeding any limits.
I am making a simple online tic tac toe game (multiplayer).
where the client side is java (android)
server side is python (linux on a shared hosting server)
My question is about the server side:
I was first thinking of having one socket (because I am only allowed to use one port on the server), then it waits for 2 users to connect and pairs them together, start a new thread to deal with them, then waits for another 2 users and so on.
But after reading here alot about multithreading I found out that the server can handle at most 20 threads.
So I tried using processes instead of threads but I got the same result.
Moreover, I found out that the socket can handle at most 50 connections.
Any Ideas?
Thanks
To scale without bounds, if you control the client code (so you know people aren't cheating -- which at tic-tac-toe they'd be unlikely to:-), you could have the client open and offer a listening socket in order to connect -- when an odd client connects, just respond with a "please wait" message; when the even client connects to match it up, respond to both clients with the listening-socket info about each other, and get out of the way.
That won't work for clients who can't open, and listen on, a new socket (e.g., ones sequestered behind some NAT arrangement). In such a situation, you could switch the clients (for their follow-on interactions with one another) to UDP to/from your server -- UDP, not being connection oriented, can serve arbitrarily high numbers of clients (client pairs, in your case!) on a single socket (but then you're responsible, cooperatively on the client and server sides!, for checking/acknowledging packets and ensuring their good ordering, which TCP, being connection-oriented, handles on your behalf:-).
I'm not sure where exactly all of your constraints come from in the first place, or what other constraints (such as clients being unable to open, communicate, and listen to, new sockets...) might apply.
But one way or another, once you fully understand and tell us about all the applicable constraints, some solution can always be found (perhaps with new-fangled conniptions such as pub-sub, e.g https://cloud.google.com/pubsub/docs -- as fast as new constraints arise, or faster!, clever guys are always figuring out work-arounds...!-)
What would happen if change both clientSocket and serverSocket to “mySocket”?
Can the client send a segment to server without knowing the server’s IP address and/or port number?
Can multiple clients use the server?
From my notes, on page 20 : http://www.cs.ucc.ie/~cjs/teach/cs2505/02-app-layer-b.pdf . Kind of confused with these.
I assume if you change both client and serverSocket to mySocket then nothing would happen, since it would only be a variable name change( I assume ).
And I assume the client can't send a message without know the IP address/port no?
And that multiple clients cannot use the server since that would require threading?
(1) Since I see no reference to mySocket other than the one in the question I would say your answer seems right.
(2) The address/port are obviously necessary. However this could be a trick question in that client could call connect() on the socket. With UDP, connect() the kernel keeps track of the address passed in the call as the peer of the socket. The socket could then just call write() or send() rather than having to use sendto(). Still, calling connect would still require the address/port in the first place so who knows what they are getting at.
(3) There is no "connection" in UDP. Many clients could send to the server. The server can get the address of the individual clients from its recvfrom and then turn around and use that address in its sendto.
I'm writing a UDP server, which is a first for me; I've only done a bit of TCP communications. And I'm having trouble figuring out exactly how to distinguish which user is which, since UDP deals only with packets rather than connections and I therefore cannot tell exactly who I'm communicating with.
Here is pseudocode of my current server loop:
DatagramPacket p;
socket.receive(p); // now p contains the user's IP and port, and the data
int key = getKey(p);
if(key == 0) { // connection request
key = makeKey(p);
clients.add(key, p.ip);
send(p.ip, p.port, key); // give the user his key
} else { // user has a key
// verify key belongs to that IP address
// lookup the user's session data based on the key
// react to the packet in the context of the session
}
When designing this, I kept in mind these points:
Multiple users may exist on the same IP address, due to the presence of routers, therefore users must have a separate identification key.
Packets can be spoofed, so the key should be checked against its original IP address and ignored if a different IP tries to use the key.
The outbound port on the client side might change among packets.
Is that third assumption correct, or can I simply assume that one user = one IP+port combination? Is this commonly done, or should I continue to create a special key like I am currently doing?
I'm not completely clear on how TCP negotiates a connection so if you think I should model it off of TCP then please link me to a good tutorial or something on TCP's SYN/SYNACK/ACK mess.
Also note, I do have a provision to resend a key, if an IP sends a 0 and that IP already has a pending key; I omitted it to keep the snippet simple. I understand that UDP is not guaranteed to arrive, and I plan to add reliability to the main packet handling code later as well.
UDP packet headers have a source port, which is generally used as the reply port. If not used, it should be zero, and then it is up to the higher level protocol to figure out how to coordinate request-response activity with multiple clients.
* The outbound port on the client side might change among packets.
Is that third assumption correct
Not if the client keeps using the same outbound socket. Sending the first datagram will cause a local bind, so the socket will be on a fixed local port from then on.
Your questions are just the tip of the iceburg WRT laundry list of issues you need to be aware of when using UDP. You should expect NAT routers to fail to provide any meaningful forwarding of a UDP protocol you design. TCP works because the routers understand the TCP state machine and store connection state of each session so they know how to forward it. They will have no idea how your custom UDP protocol works. NAT devices include specific protocol handlers for well known UDP applications.
If a sender is bound to a source port and or interface the senders source ports remain constant until unbound.
With UDP you can bind both peers to a known source port for (dst) incoming and or (src) outgoing messages. For client/server applications you typically want the client to bind to a dynamic source port so that multiple clients can co-exist on a single client system. The server can then respond to the client using the dynamic source port provided via the src port from request used as destination port in the response. Using a known port for peers allows you to configure UDP forwarding in NAT devices.
ex client/server with server on known port 3000
client binds to a random port (1234) but knows server is listening on port 3000.
client (src 1234) -> server (dst 3000)
server (dst 1234) -> client (src 3000)
...
If a computer has multiple interfaces you should expect to either need to explicitly bind a listener or sender to a specific IP address or be able to handle requests and responses from a peer being sent and recieved from a random IP based on the whims of the computers routing table. If you choose to bind requests to a specific interface then you need to be cognizant of the routing table if messages from a multi-homed system need to transit a different local interface for delivery. For example if you bind a UDP socket to 127.0.0.1 you obviously can't use it to send to any Internet routable IP Addresss.
In terms of protocol design its common to frame a session id and sequence fields in the UDP payload so that peers can keep track of sessions and individual exchanges.
There are a whole host of fragmentation, NAT coexistance, security and congestion issues you need to be aware of to successfully design a robust UDP protocol. I advise against it unless absolutely necessary.