我正在制作一个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.
代码找到这些运行的最大延迟并显示它。
答案 0 :(得分:1)
a = recv(s,reci, LENGTHVARAIBLE , 0);
strcpy(newDatagram->data[j],reci);
这是不正确的:strcpy
期望缓冲区是以空字符结尾的字符串,但是您不发送终止空字节。因此strcpy
从缓冲区读取的数据比recv
填充的更多。这里是垃圾的来源。
即使您发送终止空字节,也不能保证recv
一次读取整个消息,或者它不会在一个消息中合并多个消息(没有任何消息边界)流套接字)。
您应该在每个a
之后使用recv
个字节(并且可以使用memcpy
代替strcpy
)。要确定消息的结束位置,您可以发送零字节并在接收方查找此字节(请注意,您可以在单个recv
调用中获取多个消息),或者在每个消息前面添加一个固定的消息包含消息长度的-length头。