recv() 没有从网络中获取价值
recv() does not get value from network
我有一个典型的客户端服务器C套接字程序。
SERVER:
if(ndp.cmd == 11)
{
//ack1 = 0;
puts("Query Command for Light 2");
pthread_mutex_lock(&lock);
// ..Some critical stuff
pthread_mutex_unlock(&lock);
printf("ID: %d, Level: %d\n", new.address, new.level);
ack1 = new.level; //This result is showing correct on server
ack1 = htonl(ack1);
send(client_sock, &ack1, sizeof(ack1), 0);
}
CLIENT:
printf("Query Actual level Light2\n");
dp.id = 2;dp.cmd = 11; dp.active = 0; dp.level = 0; dp.group = 0;
if( send(sock , &dp , sizeof(dp) , 0) < 0) { puts("Send failed"); }
sleep(1);
ret = recv(sock , &level1 , sizeof(level1) , 0);
printf("Number of bytes received: %d\n", ret); //Always gives 4
fflush(stdout);
printf("Light level %x\n", ntohl(level1) ); //This prints 0 (incorrect)
fflush(stdout);
sleep(5);
printf("Query Actual level Light2\n");
dp.id = 2;dp.cmd = 11; dp.active = 0; dp.level = 0; dp.group = 0;
if( send(sock , &dp , sizeof(dp) , 0) < 0) { puts("Send failed"); }
sleep(1);
ret = recv(sock , &level2 , sizeof(level2) , 0);
printf("Number of bytes received: %d\n", ret); // Always gives 4
fflush(stdout);
printf("Light level %x\n", ntohl(level2) ); //This prints correct value
fflush(stdout);
close(sock);
Expected output:
Light level 32 (hex value for 50);
Light level 32
Actual output:
Light level 0
Light level 32
所以问题出在相同的请求上,客户端没有收到来自服务器的第一次发送,但下一个 recv() 给出了正确的值。
为什么第一个 recv() 的数据丢失了,它是否被缓冲了,也许我在第二个 recv() 中得到了以前的值?
请帮忙。
你的假设没有错。它可能被缓冲。另请注意,当接收方读取数据的速度比发送方发送数据的速度快时,某些 recv
调用可能不会读取任何数据,因为发送方尚未发送任何数据。这可能是您所描述的原因。
更新:如果您计划总是 send/receive 相同数量的数据,例如一个 20 字节的数据包,其中包含您定义的 命令 ,然后您可以将 send
和 recv
包装在一个循环中。该循环将一次写入(或读取)一条命令。你不能假设调用send
或recv
会成功,所以你必须检查错误,正如@Joachim提到的在评论中。另一件需要注意的事情是 recv
可能读取的字节数少于指定的字节数,因此您可能需要多次读取才能接收完整的 命令 。同样适用于 send
.
您可以使用select/poll机制来检查是否有新数据到达套接字并等待正确读取。您还可以通过调用 ioctl
调用来检查已到达套接字的数据量,如下所示:
{
int size = 0;
ioctl(socket, FIONREAD, &size);
if(size > 0)
{
// do recv operation(s)
}
}
我有一个典型的客户端服务器C套接字程序。
SERVER:
if(ndp.cmd == 11)
{
//ack1 = 0;
puts("Query Command for Light 2");
pthread_mutex_lock(&lock);
// ..Some critical stuff
pthread_mutex_unlock(&lock);
printf("ID: %d, Level: %d\n", new.address, new.level);
ack1 = new.level; //This result is showing correct on server
ack1 = htonl(ack1);
send(client_sock, &ack1, sizeof(ack1), 0);
}
CLIENT:
printf("Query Actual level Light2\n");
dp.id = 2;dp.cmd = 11; dp.active = 0; dp.level = 0; dp.group = 0;
if( send(sock , &dp , sizeof(dp) , 0) < 0) { puts("Send failed"); }
sleep(1);
ret = recv(sock , &level1 , sizeof(level1) , 0);
printf("Number of bytes received: %d\n", ret); //Always gives 4
fflush(stdout);
printf("Light level %x\n", ntohl(level1) ); //This prints 0 (incorrect)
fflush(stdout);
sleep(5);
printf("Query Actual level Light2\n");
dp.id = 2;dp.cmd = 11; dp.active = 0; dp.level = 0; dp.group = 0;
if( send(sock , &dp , sizeof(dp) , 0) < 0) { puts("Send failed"); }
sleep(1);
ret = recv(sock , &level2 , sizeof(level2) , 0);
printf("Number of bytes received: %d\n", ret); // Always gives 4
fflush(stdout);
printf("Light level %x\n", ntohl(level2) ); //This prints correct value
fflush(stdout);
close(sock);
Expected output:
Light level 32 (hex value for 50);
Light level 32
Actual output:
Light level 0
Light level 32
所以问题出在相同的请求上,客户端没有收到来自服务器的第一次发送,但下一个 recv() 给出了正确的值。
为什么第一个 recv() 的数据丢失了,它是否被缓冲了,也许我在第二个 recv() 中得到了以前的值?
请帮忙。
你的假设没有错。它可能被缓冲。另请注意,当接收方读取数据的速度比发送方发送数据的速度快时,某些 recv
调用可能不会读取任何数据,因为发送方尚未发送任何数据。这可能是您所描述的原因。
更新:如果您计划总是 send/receive 相同数量的数据,例如一个 20 字节的数据包,其中包含您定义的 命令 ,然后您可以将 send
和 recv
包装在一个循环中。该循环将一次写入(或读取)一条命令。你不能假设调用send
或recv
会成功,所以你必须检查错误,正如@Joachim提到的在评论中。另一件需要注意的事情是 recv
可能读取的字节数少于指定的字节数,因此您可能需要多次读取才能接收完整的 命令 。同样适用于 send
.
您可以使用select/poll机制来检查是否有新数据到达套接字并等待正确读取。您还可以通过调用 ioctl
调用来检查已到达套接字的数据量,如下所示:
{
int size = 0;
ioctl(socket, FIONREAD, &size);
if(size > 0)
{
// do recv operation(s)
}
}