Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何修复将多个TCP段合并为单个TCP段的recv?_C_Sockets_Tcp_Recv - Fatal编程技术网

如何修复将多个TCP段合并为单个TCP段的recv?

如何修复将多个TCP段合并为单个TCP段的recv?,c,sockets,tcp,recv,C,Sockets,Tcp,Recv,我有两个同龄人:爱丽丝和鲍勃。鲍勃正试图把他认识的同龄人名单寄给爱丽丝 首先,Bob告诉Alice他有多少个对等点,然后他向Alice发送带有对等点信息的n字符串 以下是Bob的代码: if ((send(socket_fd, &(int){ 1 }, sizeof(int), 0)) == -1) { perror("Failed to send"); } sleep(1); // Give him time to process the rqst send(socket_fd, &

我有两个同龄人:爱丽丝和鲍勃。鲍勃正试图把他认识的同龄人名单寄给爱丽丝

首先,Bob告诉Alice他有多少个对等点,然后他向Alice发送带有对等点信息的
n
字符串

以下是Bob的代码:

if ((send(socket_fd, &(int){ 1 }, sizeof(int), 0)) == -1) { perror("Failed to send"); }
sleep(1); // Give him time to process the rqst

send(socket_fd, &peer_cnt, sizeof(peer_cnt), 0); 
for (int i = 0; i < peer_cnt; ++i) {
    char *peer_str = get_string(&peers[i]);
    printf("Send peer\t:\t%s\n", peer_str);
    send(socket_fd, peer_str, strlen(peer_str), 0); 
    free(peer_str);
}   
if((send(socket_fd,&(int){1},sizeof(int),0))=-1{perror(“发送失败”);}
睡眠(1);//给他时间处理rqst
发送(socket\u fd和peer\u cnt,sizeof(peer\u cnt),0);
对于(int i=0;i
以下是Alice的代码:

char buf[128] = { 0 };
int n = 0;
recv(peer_sock_fd, &n, sizeof(n), 0);
printf("Number of incoming peers:\t%d\n", n); 

for (int i = 0; i < n; ++i) {
    memset(buf, '\0', sizeof(buf));
    recv(peer_sock_fd, buf, sizeof(buf), 0); 
    puts(buf);
}
charbuf[128]={0};
int n=0;
recv(peer_sock_fd,&n,sizeof(n),0);
printf(“传入对等方的数量:\t%d\n”,n);
对于(int i=0;i
例如。如果Bob发送Alice
2
字符串,则存在两种情况。 首先,Alice单独获取它们(正如我所希望的),例如,Alice的输出可能在本例中是
george:127.0.0.1:5555:
michael:127.0.0.1:4444:
。 其次,Alice将它们作为单个字符串获取,如下所示
george:127.0.0.1:5555:michael:127.0.0.1:4444:


为什么有时会合并传入字符串?

TCP是一种流协议,当您调用send()时,它会将消息一个接一个地放入一个特殊的缓冲区,然后发送它们。由于您在很短的时间内调用了多个send()系统调用,因此许多系统调用会被放入同一个缓冲区,并作为一条消息发送。有时它们将被单独发送,有时它们将被合并,有时只发送半条消息,这是流协议的默认行为。您应该做的是(这就是每一个体面的TCP程序是如何实现的)界定您的消息。最好的方法是将消息大小整数作为每条消息的前4个字节,然后根据其大小将消息分开。我建议您阅读Beej的sockets指南(),它解释了这个概念以及更多内容。非常适合初学者的

TCP是一种流协议,因此没有消息边界。您需要注意描述您的数据,而不是假设您以与发送数据相同的方式对数据进行分组。即使是第一次读取
int
时,在假设您有一个有效的int之前,您也应该先检查您是否收到了4个字节。然后,您应该在每个字符串之间设置某种形式的分隔符,以便确定字符串的结尾。您无法“修复”它,因为它没有损坏,而且不仅仅是因为
recv()
,它发生在发送方和接收方。