创建一个线程,在线程函数里,用DO.....while将来文件分块传送。部分代码如下:wsabuf[3].buf=new char[4096];
wsabuf[3].len=4096;do
{
  dwRead=sourceFile.Read(wsabuf[3].buf,4096);
  if(SOCKET_ERROR==WSASendTo(m_PresSocket,wsabuf,4,&dwSend,0,
                (SOCKADDR*)&addrto,sizeof(SOCKADDR),NULL,NULL))
{
          AfxMessageBox("系统错误1007",MB_OK,IDS_Msg);
 return 0;
}
}
while(dwRead>0);
AfxMessageBox("文件发送完成",MB_OK,IDS_Msg);
程序运行发现,如果我的文件比较小,比如小于4KB,也就是正刚好小于我定义的包大小,也就是一次调用WSASend刚好能够传送过去,那么对方就能够收到小于4KB的文件,如果我要传送的文件大于4KB的话,也就是一次WSASend不能传送过去,而是要经过DO-WHILE循环来做的话,经测试,程序第一次经DO调用WSASend似乎没有问题,但是第二资进入DO语句时程序出现死机崩溃状态,查了很久,也不知道为什么?请高手们帮帮忙!
谢谢了!

解决方案 »

  1.   

    最好不要用UDP协议,用TCP协议吧
      

  2.   

    dwRead=sourceFile.Read(wsabuf[3].buf,4096);读结尾时如果小于4096呢..
      

  3.   

    CFile myFile;
    myFile.Open("D:\\text.txt", CFile::modeRead | CFile::typeBinary); 

    int myFileLength = myFile.GetLength(); // Going to send the correct File Size

    sockRecv.Send(&myFileLength, 4); // 4 bytes long

    byte* data = new byte[myFileLength]; 

    myFile.Read(data, myFileLength);

    //sockRecv.Send(data, myFileLength); //Send the whole thing now
    for(int i=0;i<=myFileLength;i+=1024)
    {
    sockRecv.Send(data+i,1024); //Send the whole thing now
    Sleep(10);
    }
    if(myFileLength%1024!=0)
    sockRecv.Send(data+myFileLength-myFileLength%1024,myFileLength%1024);我传送文件的服务器端代码是这么写的,大家看看有没有问题
      

  4.   

    byte* data = new byte[dataLength];
    //sockClient.Receive(data, dataLength); //Get the whole thing
    for(int i=0;i<=dataLength;i+=1024)
    sockClient.Receive(data+i,1024); //Get the whole thing now
    if(dataLength%1024!=0)
    sockClient.Receive(data+dataLength-dataLength%1024,dataLength%1024);这是客户端,但不知道为什么接受的数据不对
    而且程序设置不了断点,莫名奇妙啊
      

  5.   

    HolpFalcon() ( ) 信誉:100    Blog   加为好友  2007-04-29 08:54:39  得分: 0  
     
    读文件内存超界了吧,不够4K要读4K,似乎是这样的
         dwRead=sourceFile.Read(wsabuf[3].buf,4096);
    回答:
    这个语句并非是每次都读取4KB的字节,4096是缓冲区的大小,dwRead是读取的实际字节数,如果文件不够4KB的话,那它就是读取文件的实际大小,并将读取的字节数用dwRead返回!不会发生越界的//---------------------------------------
    4102509(物到极时终必反.....) ( ) 信誉:91    Blog   加为好友 dwRead=sourceFile.Read(wsabuf[3].buf,4096);读结尾时如果小于4096呢..回答:
    读结尾如果小于4096,对于发送端应该不会出现问题,原因和上面的回答差不多,但是问题可能会出现在接收端,接收端最后一次写的时候会写入4096,这样就造成文件多写入了一些。但是我的那个问题原因不在这。我是读第一个4KB正常,读第二个4KB就死机。
    当然对于上面你的这个问题可以有解决的办法,就是每次都将读取到的实际字节数发送给对方,对方写的时候也写入这个实际节字数就行了!最后,我告诉大家,刚刚我对程序进行一点的改进,发现:
    如果我在读取一块包,将该包地送给对方,然后加了一个Sleep(1),
    也就是在WSASend函数后曾加函数Sleep(1);
    程序好像比较正常了!能分多次读取数据包并发送给对方!我想知道原因!
      

  6.   

    我给你个DEMO,[email protected]
      

  7.   

    annywoody(如果我是太阳) 
    for(int i=0;i<=myFileLength;i+=1024)
    {
    sockRecv.Send(data+i,1024); //Send the whole thing now
    Sleep(10);
    }
    if(myFileLength%1024!=0)
    sockRecv.Send(data+myFileLength-myFileLength%1024,myFileLength%1024);
    //---------------------
    看了一下你这段代码,感觉应该是在处理最后一块数据包的时候出了问题!不过我对你这个Sleep很有兴趣,不知道你为什么要用Sleep呢?我真的很想知道,也请高手们看了我上面一条回复给点意见,烦啊!
      

  8.   

    楼主这样做也有点太狠了吧
    这样做就算用TCP也很难保证稳定性的可以试一下 发一个包过去 ,
    客户端收到处理完成以后给服务器一个返回确认包
    服务器收到确认包再发一个新的
      

  9.   

    是不是 WSASend 是异步方式的?但从代码上看又好象不是在WSASend 后用 WSAGetLastError 看是不是 ERROR_IO_PENDING