首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

socket接收资料始终只能接收8KB的数据

2013-03-14 
socket接收文件始终只能接收8KB的数据客户端发送代码://m_file是CFile类型。SENDBUFFERSIZE的大小是4096whi

socket接收文件始终只能接收8KB的数据
客户端发送代码:


//m_file是CFile类型。SENDBUFFERSIZE的大小是4096
while (m_file.Read(cFileBuff,SENDBUFFERSIZE)!=0)
{
sendto(sockClient,cFileBuff,SENDBUFFERSIZE,0,(sockaddr*)&ServerInfo,sizeof(sockaddr));
}

测试过后,发现发送的数据是等于文件的大小的,即,应该是将文件发送成功了的。
问题是在接收端上,接收端用的是多线程技术,但问题应该不在这里。接收代码如下:

while (totalSize>0)
{
  unsigned long count=recvfrom(FileServer,cRecvFile,SENDBUFFERSIZE,0,
  (sockaddr *) &ClientInfo,&iLengthOfSockaddr);
  cFile.Write(cRecvFile,count);
  cFile.Flush();
  totalSize-=count;
}

totalSize的大小的确是等于文件的大小的,这点没问题。调试的时候发现,while循环始终只会执行两次,然后在第三次执行的时候就卡在了recvfrom函数上了,并且始终会卡在这里。文件是发送完毕了的,但是却始终无法完全接收。我也试过让客户端每发送一次数据,就Sleep(100),但是服务端仍然只能接收8KB的数据。
[解决办法]
检查一下recvFrom的返回值,是不是等于SOCKET_ERROR,然后看看错误码对应的原因
    iResult = recvfrom(...);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
    }

[解决办法]
用的UDP吧?
这里没有流控,也没有检查sendto的返回值,可能有一部分的sendto是失败的(可能是ENOBUFS)。

建议:sendto之前先select一下

int nfds;
FD_SET wfds, fds;
FD_ZERO(&fds);
nfds = sockClient + 1;
FD_SET(sockClient, &fds);

while (m_file.Read(cFileBuff,SENDBUFFERSIZE)!=0)
{
    wfds = fds;
    if (select(nfds, NULL, &wfds, NULL, NULL) < 0) {
        perror("select");
        break;
    }
    sendto(sockClient,cFileBuff,SENDBUFFERSIZE,0,(sockaddr*)&ServerInfo,sizeof(sockaddr));
}


[解决办法]
而且发送代码也有点问题啊
while (m_file.Read(cFileBuff,SENDBUFFERSIZE)!=0)
{
sendto(sockClient,cFileBuff,SENDBUFFERSIZE,0,(sockaddr*)&ServerInfo,sizeof(sockaddr));
}

应该读出多少,发送多少

UINT nRead;
while ((nRead = m_file.Read(cFileBuff,SENDBUFFERSIZE)) > 0)
{
sendto(sockClient,cFileBuff,nRead,0,(sockaddr*)&ServerInfo,sizeof(sockaddr));
}

[解决办法]
UDP丢包很正常,尤其调试的时候。 
[解决办法]
你在接收的时候采用的模式设置为0,代表的是每次接收缓冲区大小的数据,然后清除缓冲区,再接收发送的数据,这样2次接收的数据大小是等于发送的数据大小,但是你在每次接收到的数据都不为完整的数据;2次接收完之后,再无数据发送,就会阻塞在recvfrom函数处;从你的代码和描述我认为问题出在这个地方,你可以修改一下接收模式,采用预读的方式接收
[解决办法]
引用:
引用:用的UDP吧?
感觉应该是流量的问题,但我发送数据的时候统计了一下,发送的大小是等于文件的大小的。而且,我也怕发送的数据太快,导致接收端出现问题,尝试过每发送一次数据,就Sleep(100),但是结果仍然是只能接收到8KB的数据。

问题是:你的sendto是否成功?如果成功是否等于你希望发送的字节数,因为sendto不保证全部发送的,你请求4K, sendto可能只发送了2K啊。

http://msdn.microsoft.com/en-us/library/windows/desktop/ms740148%28v=vs.85%29.aspx

Return value

If no error occurs, sendto returns the total number of bytes sent, which can be less than the number indicated by len. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.


[解决办法]
recvefrom是阻赛的,如果数据收完了再收就处理等待了,建议每次收完数据判断是否接收完毕,如果接收完毕就处理,处理了再等待接收。
[解决办法]
不要设置为异步套接字
[解决办法]
是不是发送太快,接收端来不及接收啊。
Sleep(100)难道不够?

[解决办法]
完全绝望了!
是不是多线程的问题?
[解决办法]
将0改为MSG_PEEK就可以了,这样就是预读模式,你看看网络编程里面的参数说明吧
[解决办法]
cfile的名字接受的时候多加一个后缀名.tmp,都接受完后把.tmp去掉。不知道行不行,你试试。
[解决办法]
不知道有多少前人掉在TCP Socket
send(人多)send(病少)send(财富)
recv(人多病)recv(少财富)
陷阱里面啊!
http://topic.csdn.net/u/20120210/09/51109ed0-07b9-41f2-b487-a51597f2ca01.html

void HexDump(char *buf,int len) {
    int i,j,k;
    char binstr[80];

    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%04x -",i);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            printf("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        printf("%s\n",binstr);
    }
}

[解决办法]
接收端用的是多线程技术

那你作了同步处理没有
[解决办法]


发送采用了打包发送,这个打包是由底层协议控制的。你可以单独在调试状态下连续两次发送一个字符串,接受端看看接收情况,发送是否是两次发送都一样还是把数据拆开了发。有可能是发送完了,但是把你的数据包格式拆分开了,在接收端要注意,观察接收端收到的数据是收到了你没处理好。
[解决办法]

引用:
客户端发送代码:


C/C++ code
?



123456

//m_file是CFile类型。SENDBUFFERSIZE的大小是4096     while (m_file.Read(cFileBuff,SENDBUFFERSIZE)!=0) { sendto(sockClient,cFileBuff,SENDBUFFERSIZE,0,(sockaddr*)&amp……

建议send的时候sleep一下,就会发现,有奇迹出现了

热点排行