0

I have this simple TCP echo server, and whenever a client connects to it, it displays the client's IP and port. But when I run netstat -a, a different port for the client is shown. I'm running the server and client on the same computer.

In my program, it shows client connected: 127.0.0.1:34997, but the result of netstat -a|grep 6969 is:

tcp        0      0 0.0.0.0:6969            0.0.0.0:*               LISTEN     
tcp        0      0 localhost:46472         localhost:6969          ESTABLISHED
tcp        0      0 localhost:6969          localhost:46472         ESTABLISHED 

The code of echo server is:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>

int main(int argc,char **argv){
    int listenfd,confd,n;
    struct sockaddr_in server,client;
    pid_t pid;
    char buffer[100];

    memset(&server,0,sizeof server);
    server.sin_family=AF_INET;
    server.sin_addr.s_addr=htonl(INADDR_ANY);
    server.sin_port=htons(6969);

    listenfd=socket(AF_INET,SOCK_STREAM,0);
    
    if(bind(listenfd,(struct sockaddr *)&server,sizeof server)==-1){
        perror("bind error");return-1;
    }

    if(listen(listenfd,20)==-1){
        perror("listen error");return -1;
    }
    printf("listening for connection..\n");

    for(;;){
        socklen_t cllen = sizeof(client);
        confd=accept(listenfd,(struct sockaddr *)&client,&cllen);
        
        
        if((pid=fork())==0){    
            printf("client connected: %s:%d\n",inet_ntoa(client.sin_addr),client.sin_port);
            close(listenfd);
            for(;;){
                n=read(confd,&buffer,sizeof buffer);
                if(n==0) break;
                write(confd,&buffer,n);
            }
            printf("client disconnected: %s:%d",inet_ntoa(client.sin_addr),client.sin_port);
            exit(0);
        }
        close(confd);

    }
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
mojo
  • 61
  • 4
  • Can you show us your code so that we can try to reproduce the behavior you're asking about? – larsks Jul 22 '21 at 16:01
  • Please [edit] your question and show the code that accepts the connection and determines and prints the client's port number. – Bodo Jul 22 '21 at 16:01
  • ok i edited the post – mojo Jul 22 '21 at 16:24
  • 2
    [htons](https://linux.die.net/man/3/htons). Try printing them both in hex: they're the same two bytes in a different order. sin_port is documented as being in network byte order. – Rup Jul 22 '21 at 16:26

1 Answers1

5

You need to byte flip the client.sin_port.

printf("client connected: %s:%d\n",inet_ntoa(client.sin_addr), ntohs(client.sin_port));

34997 is 0x88B5. Flip the endianess of those bytes to 0xB588, and you have 46472, as shown in your netstat output. More information on the ntohs man page.

Note that client.sin_addr is most likely an unsigned short (see struct sockaddr_in definitions here and here, check your own system), but this will be promoted to an int, so the %d format specifier is fine.

yano
  • 4,827
  • 2
  • 23
  • 35