第一次没有正确获取客户端IP

时间:2014-11-01 18:14:34

标签: c sockets

我第一次没有获得正确的客户端IP地址。这是我的服务器主代码。

server.c

int  main()
{
    int sockfd, connfd, lisfd, retval;

    struct sockaddr_in servaddr, clntaddr;
    socklen_t client;
    struct packet pckt;
    int clnt_len;
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
            perror("socket");
            exit(1);
    }

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(8000);
    retval = bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    if(retval) {
            perror("bind");
    }

    if((lisfd = listen(sockfd, 4)) < 0) {
            perror("listen");
            exit(3);
    }
    clnt_len = sizeof(clnt_len)-1; // clnt_len = sizeof(clnt_len);
    while(1) {
            if((connfd = accept(sockfd, (struct sockaddr *)&clntaddr, &clnt_len)) < 0) {
                    perror("accept");
                    exit(2);
            }
            printf("IP address is: %s\n", inet_ntoa(clntaddr.sin_addr));

            read(connfd, &pckt, sizeof(pckt));
            printf("%s\n", pckt.msg);

    }

}

packethdr.h中声明的结构,如下所示。

struct packet {
    char msg[50];
    int cmd;
};

输出是:

IP address is: 255.127.0.0
Hi
IP address is: 127.0.0.1
Hello
IP address is: 127.0.0.1
Good
...

第一次,我得到了错误的IP。我不明白发生了什么事?如何获得正确的IP?

1 个答案:

答案 0 :(得分:1)

正如accept(2)手册页中所述,clnt_len应该在clntaddr 之前初始化为accept() 之前调用 while(1) { clnt_len = sizeof clntaddr; if ((connfd = accept(sockfd, (struct sockaddr *)&clntaddr, &clnt_len)) < 0) { perror("accept"); exit(2); } :< / p>

clnt_len = sizeof(clnt_len)-1; // clnt_len = sizeof(clnt_len);

编辑:clnt_len是有问题的一行。它将clntaddr设置为无效值:一个小于套接字长度变量的长度,当它应该是sizeof (struct sockaddr_in)中可用的内存量时。

这小于clntaddr,因此当accept()返回第一个连接时,不会分配clnt_len。确实将clntaddr分配给客户端地址的长度(是的,允许它大于其原始值;这只意味着clnt_len不够大;请参阅{{3有关详细信息),因此在以下连接中,clnt_len = sizeof clntaddr;是正确的大小,您获得第二个和更多连接的地址,只缺少初始连接地址。

要解决此问题,请将while (1)行添加到{{1}} lopp正文的开头。

有问题吗?