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).
Related
FTP RFC 959 specifies that the data connection is opened by the server from port 20 (default) to a random port in the client and known by the server through a PORT h1,h2,h3,h4,p1,p2 command. This is called Active Mode Transmission.
so that the host is h1.h2.h3.h4 while the port is p1 * 256 + p2.
My Question is: How can the server initialize multiple connections to multiple clients via the same port which is 20 by default?
Imagine client c1 has an established connection with server data port 20 and is transferring data, how can client c2 establish a connection with server if data port is already used by a TCP connection?
A server implementing Berkeley's sockets goes through a couple of phases when accepting connections. A lot of the plumbing is generally handled by the framework or the operating system, I'll try pointing them out. I'll try explaining this below with some pseudo-code.
1: Binding to the listening port
The server first asks the kernel to bind to a specific port to start listening on:
void* socket = bind(20);
2: Accepting a connection
This is probably the point that causes some misconceptions. The server gets a connection through the bound socket, but instead of using the listening port (20) to handle the communication with the new client it requests a new (random) port from the kernel to be used for a new socket connection. This is typically handled by the operating system.
void* clientSocket;
// Block until a client connects. When it does,
// use 'clientSocket' (a new socket) to handle the new client.
socket->accept(clientSocket);
// We'll use 'clientSocket' to communicate with the client.
clientSocket.send(someBuffer, ...);
// 'socket' is free again to accept more connections,
// so we can do it again:
void* clientSocket2;
socket->accept(clientSocket2);
// Of course, this is typically done in a loop that processes new connections all the time.
As a summary, what's happening is that the listener socket (20) is used only for accepting new connections. After a client establishes connection, a new socket is created to handle that specific connection.
You can test this by examining the socket connection you get as a client after establishing connection. You'll see that the remote port is not 20 anymore (it will be a random port chosen by the remote server).
All of this is shared by tcp, ftp and any protocol using the sockets protocol under its hood.
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.
I am trying to wrap my head around network sockets. So far my understanding is that a server creates a new socket that is bound to the specific port. Then it listens to this socket to deal with client requests.
I've read this tutorial http://docs.oracle.com/javase/tutorial/networking/sockets/definition.html and it says
If everything goes well, the server accepts the connection. Upon acceptance,
the server gets a new socket bound to the same local port and also has
its remote endpoint set to the address and port of the client. It needs
a new socket so that it can continue to listen to the original socket for
connection requests while tending to the needs of the connected client.
Here are a few things that I don't quite understand
If everything goes well, the server accepts the connection.
Does it mean that a client request successfully arrived at the listening socket?
Upon acceptance, the server gets a new socket bound to the same local port and
also has its remote endpoint set to the address and port of the client
The new socket is created. It also gets bound to the same port but it doesn't listen for incoming requests. After server processed client request resonse is written to this socket and then it gets closed. Is it correct?
Does it mean that request is somehow passed from the first socket to the second socket?
It needs a new socket so that it can continue to listen to the original
socket for connection requests while tending to the needs of the connected client.
So, the new socket is created then that listens for incoming request. Are there different type of sockets? Some kind of "listening" sockets and other?
Why does the server have to create a new listening socket? Why can't it reuse the previous one?
No. It means that an incoming connection arrived at the server.
No. It gets closed if the server closes it. Not otherwise.
No. It means that the incoming connection causes a connection to be fully formed and a socket created at the server to represent the server-end endpoint of it.
(a) No. A new socket is created to receive requests and send responses. (b) Yes. There are passive and active sockets. A passive socket listens for connections. An active socket sends and receives data.
It doesn't have to create a new listening (passive) socket. It has to create a new active socket to be the endpoint of the new connection.
Is new socket created for every request?
Most protocols, for example HTTP with keep-alive, allow multiple requests per connection.
1) An incoming connection has arrived
2) Socket doesn't get closed
3) There is server socket and just socket. Server socket.accept returns a socket object when a client connects
I have looked up in BSD code but got lost somewhere :(
the reason I want to check is this:
TCP RFC (http://www.ietf.org/rfc/rfc793.txt) sec 2.7 states:
"To provide for unique addresses within each TCP, we concatenate an internet address identifying the TCP with a port identifier to create a socket which will be unique throughout all networks connected together. A connection is fully specified by the pair of sockets at the ends."
Does this mean: socket = local (ip + port) ?
If yes, then the accept function of Unix returns a new socket descriptor. Will it mean that a new socket is created (in turn a new port is created) for responding to client requests?
PS: I am a novice in network programming.
[UPDATE] I understood what I read # How does the socket API accept() function work?.
My only doubt is: if socket = (local port +local ip), then a new socket would mean a new port for the same IP. going by this logic, accept returns a new socket (thus a new port is created). so all sending should occur through this new port.
Is what I understand here correct?
You are mostly correct. When you accept(), a new socket is created and the listening socket stays open to allow more incoming connections but the new socket uses the same local port number as the listening socket.
A connection is defined by a 5-tuple: protocol, local-addr, local-port, remote-addr, remote-port.
Therefore, each accepted connection is unique even though they all share the same local port number because the remote ip/port is always different. The listening socket has no remote ip/port and so is also unique.
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.