2013-10-09 54 views
0

我用tcp协议来处理客户端的请求,发现一个现象,就是使用'send'函数时丢失了一些内容。代码是作为同胞:函数'send'的某些内容丢失

_stprintf(cData,"[%s]",send_back); 
    memset(send_back,0,sizeof(cData)); 
    int send_count; 
    if((send_count=send(service_sock,cData,_tcslen(cData),0))!=SOCKET_ERROR){ 
     fwrite(cData,sizeof(char),_tcslen(cData),hFile); 
     fflush(hFile); 
     g_log->print_log("%c%c%c%c",cData[0],cData[1],cData[2],cData[send_count-1]); 
     g_log->print_log("buffer len is :%d , send %d bytes",_tcslen(cData),send_count); 
     fclose(hFile); 
     memset(cData,0,sizeof(cData)); 
     return true; 
    } 

发送功能是总是成功的,和(CDATA)_tcslen的值等于send_count和CDATA [send_count-1]是 ']'。 但是,当我使用wireshark(捕获工具)捕获由套接字发出的数据包时,我发现一些内容总是丢失,包括']'的字符。内容由JSON协议封装,所以']'是重要的。每次发送的总大小为8900字节。但是,当我将请求项目一次(之前是100)更改为50时,没有任何遗漏,发回的大小约为4000字节。 我不知道为什么会发生这种情况。

从我的日志文件中,我确定名为'cData'的数组包含全部内容,但为什么wireshark捕获的数据包中的内容不完整?

+0

有没有更晚的数据包包含其余的数据? –

+0

剩余的数据丢失,以后的数据包。 –

回答

0

看到您正在使用TCP,它已经看起来错了。

首先,TCP是不适合一次性数据包(尤其是小型)的流协议,但其优点远远大于仅使用UDP代替。 请记住,如果TPC不在控制范围内,则只能确保正确处理您的请求,实际的通信由Winsock库完成。

永远记住,发送功能LEN参数这是对你有多大的缓冲多少你可以发送一气呵成,它可能会返回小于你想要发送提示的要求,这可能取决于很多因素发生的频率,让我们说你使用回送设备,它可能永远不会这样做,这意味着发送将实际发送你所要求的。在一个真实的网络中,它可能会以大约90%或更小的概率一次性发送。

你必须确保你发送尽可能多的,即检查返回值和呼吁再发送,如果它没有发送尽可能多的,并且做同样的另一边与recv ,请致电recv,直到您获得尽可能多的数据为止。如果您确切知道要通过网络发送多少数据,此方法才有效。对于丢失数据TCP来说,假设你检查了send的返回值,我会说几乎总是发送数据。如果存在网络问题,比如丢失数据,您将看到TCP重传数据包。

为您发送的数据,这是更适合的方式,这是为了确保你真的给你想要的数据量:

xint xsend(SOCKET s,const char* buf,xint len) 
{ 
xint lastSize; 
xint result; 

    if (len==0 || s==(SOCKET)NULL || buf==(const char*)NULL) 
     return SOCKET_ERROR; 

    lastSize=0; 
    result=0; 

    do 
    { 
     result=send(s,buf+lastSize,len-lastSize,0); 

     if (result==0) 
      return 0; 
     if (result==SOCKET_ERROR) 
      return SOCKET_ERROR; 
     if (result==len) 
      return len; 
     if (result>len) 
     { 
      xlog(1,"xsend : socket sent too much data [ %i of %i ]",result,len); 
      return SOCKET_ERROR; 
     } 
     lastSize+=result; 
     if (lastSize>len) 
     { 
      xlog(1,"xsend : socket sent too much data (overall) [ %i of %i ]",result,len); 
      return SOCKET_ERROR; 
     } 
     if (lastSize==len) 
      return len; 
    } 
    while (1); 

    xlog(2,"failed to do xsend"); 
    return SOCKET_ERROR; 
} 

这个代码是刚刚从我的项目之一的复制粘贴, xlog是简单的日志记录功能,你可以算出来。