我第一次没有获得正确的客户端 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);
}
}
packet
是在 hdr.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?
最佳答案
如 accept(2) 中所述手册页中,在调用 accept()
之前,应将 clnt_len
初始化为 clntaddr
中的可用大小: p>
while(1) {
clnt_len = sizeof clntaddr;
if ((connfd = accept(sockfd, (struct sockaddr *)&clntaddr, &clnt_len)) < 0) {
perror("accept");
exit(2);
}
编辑:clnt_len = sizeof(clnt_len)-1;//clnt_len = sizeof(clnt_len);
是有问题的行。它将 clnt_len 设置为无效值:比套接字长度变量的长度小 1,而它应该是 clntaddr 中的可用内存量。
这小于 sizeof (struct sockaddr_in)
,因此当 accept()
返回第一个连接时,clntaddr
不会被分配。 clnt_len
确实被分配给客户端地址的长度(是的,它允许大于其原始值;这只是意味着 clntaddr
不够大;有关详细信息,请参阅 man page),因此在以下连接中,clnt_len
是正确的大小,并且您将获得第二个和后续连接的地址,仅缺少初始连接地址。
要修复此问题,请将 clnt_len = sizeof clntaddr;
行添加到 while (1)
lopp 主体的开头。
有疑问吗?
关于c - 第一次无法正确获取客户端IP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26691476/