嘿所有,我对recv()有这个奇怪的问题。我正在编程客户端/服务器,其中客户端发送()消息(结构准确)和服务器recv()它。我也在使用多个套接字和select()。
while(1)
{
readset = info->read_set;
info->copy_set = info->read_set;
timeout.tv_sec = 1;
timeout.tv_usec = 0; // 0.5 seconds
ready = select(info->max_fd+1, &readset, NULL, NULL, &timeout);
if (ready == -1)
{
printf("S: ERROR: select(): %s\nEXITING...", strerror(errno));
exit(1);
}
else if (ready == 0)
{
continue;
}
else
{
printf("S: oh finally you have contacted me!\n");
for(i = 0; i < (info->max_fd+1); i++)
{
if(FD_ISSET(i, &readset)) //this is where problem begins
{
printf("S: %i is set\n", i);
printf("S: we talking about socket %i son\n", i); // i = 4
num_bytes = recv(i, &msg, MAX_MSG_BYTE, 0);
printf("S: number of bytes recieved in socket %i is %i\n", i, num_bytes); // prints out i = 0 what??
if (num_bytes == 0)
{
printf("S: socket has been closed\n");
break;
}
else if (num_bytes == -1)
{
printf("S: ERROR recv: %d %s \n", i, strerror(errno));
continue;
}
else
{
handle_request(arg, &msg);
printf("S: msg says %s\n", msg->_payload);
}
} // if (FD_ISSET(i, &readset)
else
printf("S: %i is not set\n", i);
} // for (i = 0; i < maxfd+1; i++) to check sockets for msg
} // if (ready == -1)
info->read_set = info->copy_set;
printf("S: copied\n");
}
我遇到的问题是在read_set
中,0~3未设置,4是。那样就好。但当我打电话给recv()
时,i
突然变为0.为什么?对我来说,为什么recv()
将获取套接字文件描述符号并修改为另一个数字是没有意义的。这是正常的吗?我错过了什么吗?
S: 0 is not set
S: 1 is not set
S: 2 is not set
S: 3 is not set
S: 4 is set
S: we talking about socket 4 son
S: i is strangely or unstrangely 0
S: number of bytes recieved in socket 0 is 40
这就是打印出来的东西。
答案 0 :(得分:2)
recv
无法修改其第一个参数,因为它是按值获取的。
您没有显示您已声明msg
或i
的位置,但基于此行
printf("S: msg says %s\n", msg->_payload);
如果您在->
上使用msg
运算符,我认为它可能是这样的:
struct somestruct* msg = malloc(sizeof(struct somestruct));
int i;
然后你这样做:
num_bytes = recv(i, &msg, MAX_MSG_BYTE, 0);
请注意,msg
已经指针,因此&msg
是指向的指针。
接下来要做的是接收数据并尝试将其存储在msg
指针本身所在的位置,而不是msg
指向的位置到。通常,指针只有4个字节长,因此如果您收到的字节数超过4个,这将溢出存储空间。如果在i
之后在堆栈上声明msg
,则很可能它被此溢出覆盖,并且它恰好被接收到的数据包中的所有零字节覆盖。
由于msg
已经是指针,因此请更改接收行以消除多余的间接:
num_bytes = recv(i, msg, MAX_MSG_BYTE, 0);
同样,您可能需要考虑对该行进行相同的更改
handle_request(arg, &msg)
如果handle_request
函数并不真正期望指向指针。
答案 1 :(得分:1)
我的第一个猜测是sizeof(msg) < MAX_MSG_BYTE
,当recv
溢出msg
时,它会导致i
。