Beej的有关套接字编程的指南/教程给出了通过send
发送所有数据的简单易用的代码段。它称为sendall
,并在此处提供-http://beej.us/guide/bgnet/html/single/bgnet.html#sendall
即使声明recv
也可以是部分的,也没有为recv
全部提供这样的权威性指南。为什么?
另外,我如何编写与recvall
的建议类似的非阻塞sendall
函数。尽管没有简单的答案,但这似乎是FAQ。
最佳答案
您最初的想法行不通。如果recv()
已读取所有已发送的字节,则它将阻塞,除非并且直到发送了更多字节为止。如果没有发送任何邮件,则说明您被困住了。正如上面的评论者所述,您需要某种方式来告知何时到达传输结束。
您可以采用两种方法。最简单的方法是在发送完所有数据后仅在发送端关闭套接字。 recv()
然后将在适当时候返回0,并且您知道期望的所有数据都已到达。
另一种稍微困难一点的方法是在消息本身之前发送消息的长度。这很简单。在发送端(为简便起见,省略了错误检查):
uint32_t msg_len = ...;
uint32_t network_byte_order_msg_len = htonl (msg_len);
int nbytes = sizeof (network_byte_order_msg_len);
sendall (skt, sizeof (uint32_t), &network_byte_order_msg_len, &nbytes);
nbytes = msglen;
sendall (skt, my_msg_buf, &nbytes);
在接收端,假设我们有一个函数
recv_bytes
,它在循环中调用recv
直到获得要查找的字节数:uint32_t network_byte_order_msg_len;
int nbytes = sizeof (network_byte_order_msg_len);
recv_bytes (skt, &network_byte_order_msg_len, nbytes);
int msg_len = ntohl (&network_byte_order_msg_len);
void *msg_buf = malloc (msg_len);
nbytes = msg_len;
recv_bytes (skt, msg_buf, &nbytes);
请注意,通过这种方式,我们可以立即在接收方中分配适当大小的消息缓冲区,这既好又有效。
您可以写
recv_bytes()
吗?如果愿意,可以将实现编辑到我的帖子中,以供将来的访客使用。编辑:该代码是C ++,我确定您可以修复它。
关于c - C插槽可处理全部接收,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50788713/