how listening to a socket works - sockets

If a client listens on a socket, at http://socketplaceonnet.com for example, how does it know that there is new content? I assume the server cannot send data directly to the client, as the client could be behind a router, with no port forwarding so a direct connection is not possible. The client could be a mobile phone which changes it's IP address. I understand that for the client to be a listener, the server doesn't need to know the client's IP.
Thank you

A client socket does not listen for incoming connections, it initiates an outgoing connection to the server. The server socket listens for incoming connections.
A server creates a socket, binds the socket to an IP address and port number (for TCP and UDP), and then listens for incoming connections. When a client connects to the server, a new socket is created for communication with the client (TCP only). A polling mechanism is used to determine if any activity has occurred on any of the open sockets.
A client creates a socket and connects to a remote IP address and port number (for TCP and UDP). A polling mechanism can be used (select(), poll(), epoll(), etc) to monitor the socket for information from the server without blocking the thread.
In the case that the client is behind a router which provides NAT (network address translation), the router re-writes the address of the client to match the router's public IP address. When the server responds, the router changes its public IP address back into the client's IP address. The router keeps a table of the active connections that it is translating so that it can map the server's responses to the correct client.

The TCP Iterative server accepts a client's connection, then processes it, completes all requests from the client,
and disconnects. The TCP iteration server can only process one client's request at a time. Only when all the
requests of the client are satisfied, the server can continue the subsequent requests. If one client occupies the
server, other clients can't work, so TCP servers seldom use the iterated server model.

Related

Understanding of WebSockets

My understanding is that a socket corresponds to a network identifier, port and TCP identifier. [1]
Operating systems enable a process to be associated with a port (which IIUC is a way of making the process addressable on the network for inbound data).
So a WebSocket server will typically be associated with a port well-known for accepting and understanding HTTP for the upgrade request (like 443) and then use TCP identifiers to enable multiple network sockets to be open concurrently for a single server process and a single port.
Please can someone confirm or correct my understanding?
[1] "To provide for unique names at
each TCP, we concatenate a NETWORK identifier, and a TCP identifier
with a port name to create a SOCKET name which will be unique
throughout all networks connected together." https://www.rfc-editor.org/rfc/rfc675
When a client connects to your server on a given port, the client connection is coming from an IP address and a client-side port number. The client-side port number is automatically generated by the client and will be unique for that client. So, you end up with four items that make a connection.
Server IP address (well known to all clients)
Server port (well known to all clients)
Client IP address (unique for that client)
Client port (dynamically unique for that client and that socket)
So, it is the combination of these four items that make a unique TCP connection. If the same client makes a second connection to the same server and port, then that second connection will have a different client port number (each connection a client makes will be given a different client port number) and thus the combination of those four items above will be different for that second client connection, allowing it's traffic to be completely separate from the first connection that client made.
So, a TCP socket is a unique combination of the four items above. To see how that is used, let's look at how some traffic flows.
After a client connects to the server and a TCP socket is created to represent that connection, then the client sends a packet. The packet is sent from the client IP address and from the unique client port number that that particular socket is using. When the server receives that packet on its own port number, it can see that the packet is coming from the client IP address and from that particular client port number. It can use these items to look up in its table and see which TCP socket this traffic is associated with and trigger an event for that particular socket. This separates that client's traffic from all the other currently connected sockets (whether they are other connections from that same client or connections from other clients).
Now, the server wants to send a response to that client. The packet is sent to the client's IP address and client port number. The client TCP stack does the same thing. It receives the packet from the server IP/port and addressed to the specific client port number and can then associate that packet with the appropriate TCP socket on the client so it can trigger an event on the right socket.
All traffic can uniquely be associated with the appropriate client or server TCP socket in this way, even though many clients may connect to the same server IP and port. The uniqueness of the client IP/port allows both ends to tell which socket a given packet belongs to.
webSocket connections start out with an HTTP connection (which is a TCP socket running the HTTP protocol). That initial HTTP request contains an "upgrade" header requesting the server to upgrade the protocol from HTTP to webSocket. If the server agrees to the upgrade, then it returns a response that indicates that the protocol will be changed to the webSocket protocol. The TCP socket remains the same, but both sides agree that they will now speak the webSocket protocol instead of the HTTP protocol. So, once connected, you then have a TCP socket where both sides are speaking the webSocket protocol. This TCP connection uses the same logic described above to remain unique from other TCP connections to the same server.
In this manner, you can have a single server on a single port that works for both HTTP connections and webSocket connections. All connections to that server start out as HTTP connections, but some are converted to webSocket connections after both sides agree to change the protocol. The HTTP connections that remain HTTP connections will be typical request/response and then the socket will be closed. The HTTP connections that are "upgraded" to the webSocket protocol will remain open for the duration of the webSocket session (which can be long lived). You can have many concurrent open webSocket connections that are all distinct from one another while new HTTP connections are regularly serviced all by the same server. The TCP logic above is used to keep track of which packets to/from the same server/port belong to which connection.
FYI, you may have heard about NAT (Network Address Translation). This is commonly used to allow private networks (like a home or corporate network) to interface to a public network (like the internet). With NAT a server may see multiple clients as having the same client IP address even though they are physically different computers on a private network). With NAT, multiple computers are routed through a common IP address, but NAT still guarantees that the client IP address and client port number are still a unique combination so the above scheme still works. When using NAT an incoming packet destined for a particular client arrives at the shared IP address. The IP/port is then translated to the actual client IP address and port number on the private network and then packet is forwarded to that device. The server is generally unaware of this translation and packet forwarding. Because the NAT server still maintains the uniqueness of the client IP/client port combination, the server's logic still works just fine even though it appears that many clients are sharing a common IP address). Note, home network routes are usually configured to use NAT since all computers on the home network will "share" the one public IP address that your router has when accessing the internet.
You will not enable multiple sockets, there is no need for it. You will have multiple conections. It's a little different, but you undesrstand well. For UDP there's nothing to do, cause there is no connections.
In TCP, if two different machines connect to the same port on a third machine, there are two distinct connections because the source IPs differ. If the same machine (or two behind NAT or otherwise sharing the same IP address) connects twice to a single remote end, the connections are differentiated by source port, the same machine cannot open 2 connections on the same port.

UDP client not receiving reply from server with multiple IP addresses

I have a UDP client that calls connect(), send() and recv().
The server has multiple IP addresses. If the reply from the server is not from the same IP as the query, then recv() times out. I have read elsewhere that this might be because the client is calling connect(), so it will only accept a reply from the same IP.
Is there a way to ensure the server always replies from the same IP as the query? I would like the server to listen on all interfaces.
Update: If the client does not call connect() and calls sendto() instead of send(), then recv() correctly receives the reply from the server. I would still rather fix it on the server side by sending the reply from the same IP that the query came from. There is no routing happening on the server, it's one network interface with several IPs.
This makes sense if the client calls connect to one IP address and port, it won't receive a UDP datagram sent from a different IP or port.
If you want your server to listen on all ip's and all ports you'll need to program at the ethernet layer (raw sockets). Check out this link.
When programming in raw sockets you can check in your code for the IP address that the datagrams were addressed to and respond from the appropriate IP.

On successful TCP connection between server and client

RELATED POST
The post here In UNIX forum describes
The server will keep on listeninig on a port number.
The server will accept a clients connect() request using accept(). As soon as the server accepts the client request, the kernel allocates a random port number for the server for further send() and receive(), since the same port number on the server can't be used for sending as well as listening, and the previous port is still listening for new connections
QUESTION
I have a server application S which is constantly listening on port 18333 (this is actually bitcoind testnet). When another client node C connects with it on say 53446 (random port). According to the above post, S will be able to send/receive data of 'C' only from port 53446.
But when I run a bitcoind testnet. This perfectly communicates with other node with only one socket connection in port 18333 without need for another for sending/receiving. Below is snippet and I even verified this
bitcoin-cli -testnet -rpcport=16591 -datadir=/home/user/mytest/1/
{
"id": 1,
"addr": "178.32.61.149:18333"
}
Can anyone help me understand what is the right working in TCP socket connection?
A TCP connection is identified by a socket pair and this is uniquely identified by 4 parameters :
source ip
source port
dest ip
dest port
For every connection that is established to a server the socket is basically cloned and the same port is being used. So for every connection you have a socket using the same server port. So you have n+1 socket using the same port when there are n connections.
The TCP kernel is able to make distinction between all these sockets and connections because the socket is either in the listening state, or it belongs to the socket pair where all 4 parameters are considered.
Your second bullet is therefore wrong because the same port is being used as i explained above.
The server will accept a clients connect() request using accept(). As
soon as the server accepts the client request, the kernel allocates a
random port number for the server for further send() and receive().
On normal TCP traffic this is not the case. If a webserver is listening on port 80, all packets sent back to the client wil be over server port 80 (this can be verified with WireShark for example) - but there will be a different socket for each connection (srcIP:port - dstIP:port). That information is sent in the headers of the network packets - IP and protocol code (TCP, UDP or other) in the IP header, port numbers as part of the TCP or UDP header).
But changing ports can happen when communicating over ftp, where there can be a control port (ususally 21) and a negotiated data port.

In TCP, if the server uses another port to communicate, how will it inform the client?

I'm studying socket programming in C. In TCP communication, a classical situation is that once the server accept() a connect() request from a client, it will fork a new process to handle this communication. Then the child process will use another port to communicate with the client. My question is, how does the server inform the client that it will use another port rather than the original one to do the subsequent communication? Which field in the TCP header and which phase of the handshake can reflect the port change?
For example, process PA on server A is listening to its port 80. Now process PB on client B wants to connect to A's port 80. Once PA accepts PB's connecting request, it will fork a new process PA1 to handle the communication with PB. Am I right till now? Next, will PA1 still use port 80 or another port such as 1234 to communication with PB? If it still uses 80, how can the server A distribute PB's communication to PA1? If it uses another port like 1234, how will the server A inform PB to use 1234 for the subsequent communication?
A TCP connection is uniquely identified by the tuple (source ip, source port, destination ip, destinatin port). These tuple is used by OS to "bind" the TCP connection to a process, meaning to know which process the OS should deliver the TCP package to.
When server socket accepts the TCP connection and fork, that process inherits the original process so it effectively take up the binding of the TCP connection to this newly forked process. The client in the remote machine does not know and does not need to know such thing happens. The whole network keeps seeing the same thing, the package of the same tuple flow through the network.
At this time, the original process will keep listening to new TCP connection. When new TCP connection request arrive, even it is from the same previous machine, the port must be different. In OS's perspective it is a different tuple, therefore it can distinguish the TCP pcakge and deliver to the right process.
You may ask why the client from the remote machine knows it has to use another port to initiate a new connection. This is simply because the client OS knows (or informed by the socket library) that this process is creating a separate new connection. OS will assign another unique port number to the process. That's how it is possible for multiple processes communicating to the same server port without message mess up.
To put it short, the operation of accept and fork in server is just a kind of transferring the ownership of a TCP connection binding to another process. Nothing change in the server port used in this communication.
In TCP communication, a classical situation is that once the server accept() a connect() request from a client, it will fork a new process to handle this communication.
Correct, or start a thread.
Then the child process will use another port to communicate with the client.
No. It will use the same port, via the accepted socket, inherited in the case of a child process.
My question is, how does the server inform the client that it will use another port rather than the original one to do the subsequent communication?
It doesn't, because this isn't the 'classical situation'.
Which field in the TCP header and which phase of the handshake can reflect the port change?
None. It doesn't happen that way. It would be a waste of a port.
For example, process PA on server A is listening to its port 80. Now process PB on client B wants to connect to A's port 80. Once PA accepts PB's connecting request, it will fork a new process PA1 to handle the communication with PB. Am I right till now?
Yes.
Next, will PA1 still use port 80 or another port such as 1234 to communication with PB?
Port 80.
If it still uses 80, how can the server A distribute PB's communication to PA1?
By inheritance of the accepted socket.
If it uses another port like 1234, how will the server A inform PB to use 1234 for the subsequent communication?
Doesn't happen.
The client chooses this port, not the server. The client will choose a port that's not already in use on that particular machine, and use that port to tell its connections apart (just as the server does).
For example say the client has IP address 1.2.3.4 and the server has IP address 4.3.2.1 and listens on port 80. If the client has two connections to that server and port, how will it tell them apart? Simple -- it assigns a different source port to each one. Say one gets port 50001 and one gets port 50002, then the two connections are:
1.2.3.4:50001 -> 4.3.2.1:80
and
1.2.3.4:50002 -> 4.3.2.1:80
The server knows these ports because it gets them from the TCP SYN packets sent from the client to the server. So the client tells the server, not the other way around.

Server/Client using socket programming

Let's say I have a server socket listening on port no 5010. When client tries to connect to this server socket using connect() API, server accepts socket connection in accept() API.
accept() API returns a new socket for server/client connection. Now all data transfer between server and client is done using this newly created socket. Does the data transfer happens on same port 5010. If not, how the ports are chosen when new socket is returned as a result of accept() API ?
The connection between the server and the client socket is identified by the tuple (serverAddress, serverPort, clientAddress, clientPort). The server address and server port always stay the same (obviously). The client allocates a (semi-)random "source" port to avoid collisions even if re-using the same address (e.g. when there are multiple clients on the same machine).