2014-04-27 50 views
0

我正在创建一个从服务器向客户端发送数据的TCP客户端服务器程序(此工作正常),然后将其回显给服务器(不会“工作正常)。当使用recv函数时,第一次接收数据的效果很好,但之后大量垃圾进入,数据本身也出现了,但是在大量垃圾中,recv/send返回值始终是正确的。除此之外,我第一次在启动电脑后开始测试这个程序要好得多(通常是有效的)。有没有人有关于为什么的想法?我相信有些缓冲区已满或recv的不再是一个阻塞函数莫名其妙...... 在此先感谢... 这是客户端的代码:winsock 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

这个'std :: stod'看起来不像C. – alk

+0

当你发送'strlen()'时,你没有发送字符串的终止符。无论如何,这是一个糟糕的主意,因为如果发送数据大于MTU,它可能会被分成多个数据包。你应该发送一个长度前缀(如何以及以什么格式留给你)以及字符串数据,然后使用这两个字符串在另一侧重新组装字符串,一旦你阅读足够的时间来满足这个长度。 – WhozCraig

+0

这条线看起来像一个无限循环:while(head-> general [0]!='b');此外,您的数据不会以与发送的大小相同的大小块到达,您需要将数据放在接收端。还有一件事,为了确保您的数字数据得到正确发送和到达,请查看主机到网络的转换功能(htons,htond等)以及相反的操作。 – DNT

回答

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

这是不正确的:strcpy预计缓冲区是空值终止字符串,但您不发送终止空字节。所以strcpy从缓冲区读取的数据比recv填充的更多。这里是垃圾的来源。

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

你应该确切使用a字节每recv后(也许使用memcpy代替strcpy)。要确定消息的结束位置,您可以发送零字节并在接收端查找该字节(请注意,您可以在单个调用中获取多条消息),也可以在每条消息的前面添加一个固定长度的头部消息的长度。