c - winsock recv 函数在相关数据之间接收垃圾

标签 c client-server winsock recv

我正在制作一个 TCP 客户端-服务器程序,该程序将数据从服务器发送到客户端(这工作正常),然后将其回显到服务器(工作不正常)。当使用recv函数时,第一次接收数据工作正常,但之后有很多垃圾进来,数据本身也进来,但在很多垃圾中间,recv/send返回值总是正确的。除此之外,我在启动计算机后第一次开始测试该程序要好得多(通常有效)。有人知道为什么吗?我相信某些缓冲区已填满或者recv 不再是阻塞函数...... 提前致谢... 这是客户的代码:

    for(i=0;i<FIRSTSENDING;i++)  
      //the buffer is a chained-list with 4 fields per struct ( x,y,z,time )
{
    for(j=0;j<NUMBEROFVARIABLES;j++)
    {
        while(head->data[j][0]!='b'); //the data has a 'b' at first and 'e'
                                                    in the end.
        b1 = send(t,head->data[j],strlen(head->data[j]),0);
    }
    while(head->general[0]!='b');
    b1 = send(t,head->general,strlen(head->general),0);
    temp = head;
    head = head->next;
    free(temp);
}

服务器的代码是:

    for(i=0;i<FIRSTSENDING;i++)
{
    for(j=0;j<NUMBEROFVARIABLES;j++)
    {
        newDatagram->data[j][0]=0;
        a = recv(s,reci, LENGTHVARAIBLE , 0);
        strcpy(newDatagram->data[j],reci);
        newDatagram->data[j][LENGTHVARAIBLE] = 0;
    }
    newDatagram->general[0]=0;
    a = recv(s,reci, LENGTHTIME , 0);
    strcpy(newDatagram->general,reci);
    newDatagram->general[LENGTHTIME] = 0;
    _ftime(&timebuffer); 
     //fixing the time and sending it
    timer=(double)(timebuffer.millitm)/1000+timebuffer.time;
    newDatagram->general[LENGTHTIME-1]=0;
    pointerTime = &newDatagram->general[1];
    if(newDatagram->general[0]=='b')
    {
        attol=std::stod(pointerTime);
        if((timer-attol)>delay1)
            delay1=timer-attol;
    }
}
delay1=delay1/10*15*1000; //adding 10 percent and making milli the right delay
delay=(int)(delay1);
delay=delay% 100000;
nextDelay=delay;
printf("The first delay is: %d in milliseconds\n",delay);               //This is an incriment of 10% to the delay.

代码找到这些运行的最大延迟并显示它。

最佳答案

a = recv(s,reci, LENGTHVARAIBLE , 0);
strcpy(newDatagram->data[j],reci);

这是不正确的:strcpy 期望缓冲区是一个以 null 结尾的字符串,但您不发送以 null 结尾的字节。因此,strcpy 从缓冲区读取的数据多于 recv 填充的数据。这就是垃圾的来源。

即使您发送终止空字节,您也不能保证 recv 立即读取整个消息,或者它不会将多个消息合并为一个消息(没有任何消息)流套接字中的消息边界)。

您应该在每个 recv 之后使用恰好 a 字节(也许使用 memcpy 而不是 strcpy)。要确定消息的结束位置,您可以发送零字节并在接收端查找该字节(请注意,您可以在一次 recv 调用中获取多条消息),或者在每条消息前面添加带有包含消息长度的固定长度 header 。

关于c - winsock recv 函数在相关数据之间接收垃圾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23324626/

相关文章:

c - '错误: scheduling while atomic' with crypto_alloc_hash

c - 客户端服务器实现的命名管道-服务器如何区分来自同一客户端的两个请求

c++ - libcurl : output of network upload download speed is not accurate

c - 我如何按照 MATLAB 语法编写此 C 代码片段?

C++ 低吞吐量 winsock TCP 测试应用程序

tcp - 如何等到您的 TCP 消息被确认

sockets - mqtt 协议(protocol)中订阅者的反馈消息

C中的客户端服务器多个连接

c++ - 如何制作同步聊天程序来同步发送和接收消息?

performance - Windows Server 2008 上的 UDP 性能上限