Jerry Feldman wrote:
On Wednesday 02 February 2005 09:48, Davi de Castro Reis wrote:
This is not true. The source port is assigned by the kernel, and the destination port is programatically set by the server. They do not change after a connect()/accept(). Take a look at netstat or tcpdump output. There are _applications_ that do work like this, like ftp. But, by some reason, they teach that every tcp connection works this way in the university.
That is what I said. I think you are confused.
Hum. Sorry. Maybe we are saying the same thing. But I couldn't really get it from your previous schematics. Let us check it out.
First, the client chooses the destination IP address and the destination port. The Server chooses the the port on which it listens.
Ok.
So, for the client, the destination port (eg. for telnet is 23) and the source port is assigned by the kernel. On the server side, the accept system call creates a new socket,
Yes.
and the source and destination port are both assigned by the kernel.
No. The destination (the server port) is the same of the original socket.
Since the listen socket is bound (see bind(2)) to the original port, the new socket created by the accept(2) call on the server side. It uses a new port assigned by the kernel as its receiving port,
No new port. The port is the same of the socket you called listen(2) at. and uses the client's source
port that was assigned by the client's kernel.
Yes. That is correct. In the whole process, there are only two ports involved. One given by the kernel (client), the other programatically set by the server. C code for simple server and simple client in the end of the message. []s Davi de Castro Reis //Server code #include <sys/types.h> #include <sys/socket.h> #include <assert.h> #include <stdio.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <unistd.h> int main(int argc, char **argv) { int c = 0; struct sockaddr_in addr; struct sockaddr_in newaddr; socklen_t newaddr_len; struct in_addr ip; int s = socket(PF_INET, SOCK_STREAM, 0); memset(&ip, 0, sizeof(ip)); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr = ip; addr.sin_port = htons(1025); c = bind(s, (struct sockaddr *)(&addr), sizeof(addr)); assert(c != -1); c = listen(s, 1); assert(c != -1); c = accept(s, (struct sockaddr *)(&newaddr), &newaddr_len); //Check port assigned by the kernel in the client side fprintf(stderr, "Client port: %u\n", ntohs(newaddr.sin_port)); sleep(100); return 0; } //Client code #include <sys/types.h> #include <sys/socket.h> #include <assert.h> #include <stdio.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <unistd.h> int main(int argc, char **argv) { int c = 0; struct sockaddr_in addr; struct in_addr ip; int s = socket(PF_INET, SOCK_STREAM, 0); memset(&ip, 0, sizeof(ip)); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr = ip; addr.sin_port = htons(1025); c = connect(s, (struct sockaddr *)&addr, sizeof(addr)); assert(c != -1); //Port programatically set by the server fprintf(stderr, "Server port: %u\n", ntohs(addr.sin_port)); sleep(100); return 0; }