Woody
Woody

Reputation: 11

getpeername() from listening(server) socket

I'm trying to do socket programming. I made some example, which is getting ip and port from sockets.

I tried to get IP and port in server and client both.

server has two sockets, listening socket and socket for data transfer with client(I named it "Client socket"). and client has one socket. I wanted these socket's local ip&port and peer's ip&port.so I used getsockname() and getpeername().

code is below.

** server **

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

void error_handling(char *message);

int main(int argc, char *argv[])
{
    int serv_sock;
    int clnt_sock;

    struct sockaddr_in serv_addr;
    struct sockaddr_in clnt_addr;
    socklen_t clnt_addr_size;

    char message[]="Hello World!";

    if(argc!=2){
        printf("Usage : %s <port>\n", argv[0]);
        exit(1);
    }

    serv_sock=socket(PF_INET, SOCK_STREAM, 0);
    if(serv_sock == -1)
        error_handling("socket() error");

    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family=AF_INET;
    serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    serv_addr.sin_port=htons(atoi(argv[1]));



    if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr))==-1 )
        error_handling("bind() error"); 

    if(listen(serv_sock, 5)==-1)
        error_handling("listen() error");



    clnt_addr_size=sizeof(clnt_addr);  
    clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_addr,&clnt_addr_size);
    if(clnt_sock==-1)
        error_handling("accept() error");  

    write(clnt_sock, message, sizeof(message));

    struct sockaddr_in addr1;
    struct sockaddr_in addr2;

    struct sockaddr_in addr3;
    struct sockaddr_in addr4;

    socklen_t serv_len = sizeof(serv_addr);
    int serv_peer_err = getpeername(serv_sock, (struct sockaddr *)&addr1, &serv_len);
    int clnt_peer_err = getpeername(clnt_sock, (struct sockaddr *)&addr2, &clnt_addr_size);

    int serv_sock_err = getsockname(serv_sock, (struct sockaddr *)&addr3, &serv_len);
    int clnt_sock_err = getsockname(clnt_sock, (struct sockaddr *)&addr4, &clnt_addr_size);

    printf("Server socket's ip : %s\n", inet_ntoa(addr3.sin_addr));
    printf("Server socket's port : %d\n", ntohs(addr3.sin_port));
    printf("Server socket's peer ip : %s\n", inet_ntoa(addr1.sin_addr));
    printf("Server socket's peer port : %d\n\n\n\n\n\n", ntohs(addr1.sin_port));



    printf("Client socket's ip : %s\n", inet_ntoa(addr4.sin_addr));
    printf("Client socket's port : %d\n", ntohs(addr4.sin_port));
    printf("Client socket's peer ip : %s\n", inet_ntoa(addr2.sin_addr));
    printf("client socket's peer port %d\n", ntohs(addr2.sin_port));

    printf("%d %d %d %d\n", serv_peer_err, clnt_peer_err, serv_sock_err, clnt_sock_err);


    close(clnt_sock);   
    close(serv_sock);
    return 0;
}

void error_handling(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

** client **

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

void error_handling(char *message);

int main(int argc, char* argv[])
{
    int sock;
    struct sockaddr_in serv_addr;
    char message[30];
    int str_len;

    if(argc!=3){
        printf("Usage : %s <IP> <port>\n", argv[0]);
        exit(1);
    }

    sock=socket(PF_INET, SOCK_STREAM, 0);
    if(sock == -1)
        error_handling("socket() error");

    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family=AF_INET;
    serv_addr.sin_addr.s_addr=inet_addr(argv[1]);
    serv_addr.sin_port=htons(atoi(argv[2]));

    if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1) 
        error_handling("connect() error!");

    str_len=read(sock, message, sizeof(message)-1);
    if(str_len==-1)
        error_handling("read() error!");

    struct sockaddr_in addr1;
    struct sockaddr_in addr2;

    int clnt_sock_err, clnt_peer_err;
    socklen_t serv_len = sizeof(serv_addr);
    clnt_peer_err = getpeername(sock, (struct sockaddr *)&addr1, &serv_len);
    clnt_sock_err = getsockname(sock, (struct sockaddr *)&addr2, &serv_len);

    printf("Client socket's ip : %s\n", inet_ntoa(addr2.sin_addr));
    printf("client socket's port %d\n", ntohs(addr2.sin_port));
    printf("Client socket's peer ip : %s\n", inet_ntoa(addr1.sin_addr));
    printf("Client socket's peer port : %d\n", ntohs(addr1.sin_port));

    printf("%d %d\n", clnt_sock_err, clnt_peer_err);



    printf("Message from server: %s \n", message);  
    close(sock);
    return 0;
}

void error_handling(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

and I run it, ip is loopback(127.0.0.1) and port is 7755.

the result is :

server

Server socket's ip : 0.0.0.0

Server socket's port : 7755

Server socket's peer ip : 1.0.0.0

Server socket's peer port : 4992

Client socket's ip : 127.0.0.1

Client socket's port : 7755

Client socket's peer ip : 127.0.0.1

client socket's peer port 6311

-1 0 0 0

client

Client socket's ip : 127.0.0.1

client socket's port 6311

Client socket's peer ip : 127.0.0.1

Client socket's peer port : 7755

0 0

Message from server: Hello World!

I noticed getpeername() failed with server socket's peer, then returned -1. but it showed IP and port : 1.0.0.0 and 4992. I don't know what these mean. and I think another results make sense. I know listening(server) socket only deal with connection, not data transfer, server create another socket for data transfer by accept().

my question is ㅡ if listening(server) socket only deal with client's connection, then its peer should not be exist? what's that wrong IP and Port? just garbage value?

Upvotes: 1

Views: 6582

Answers (2)

Steffen Ullrich
Steffen Ullrich

Reputation: 123365

if listening(server) socket only deal with client's connection, then its peer should not be exist?

Correct, there is no peer for a server socket. That's why getpeername returned an error as you already noticed.

what's that wrong IP and Port? just garbage value?

Since getpeername returns an error you cannot interpret the value of addr1 in any meaningful way. It is probably just the same as you would have in addr if you did not call getpeername in the first place: garbage because you don't initialize addr1 explicitly by your own and because C does not initialize data implicitly.

Upvotes: 0

user207421
user207421

Reputation: 310957

getpeername() from listening(server) socket

The listening (server) socket doesn't have a peer. It is a local, unconnected, listening socket, with no remote endpoint. No peer, no peername.

I noticed getpeername() failed with server socket's peer, then returned -1. but it showed IP and port : 1.0.0.0 and 4992.

If it failed, whatever else it may have done is irrelevant.

I don't know what these mean.

They don't mean anything. They are just junk left over in the buffer, which was not modified, because there was an error instead.

and I think another results make sense.

No result makes sense. There is no result to obtain. Only an error.

I know listening(server) socket only deal with connection, not data transfer, server create another socket for data transfer by accept().

Correct.

my question is ㅡ if listening(server) socket only deal with client's connection, then its peer should not be exist?

Correct.

what's that wrong IP and Port? just garbage value?

Yes.

Upvotes: 0

Related Questions