为什么循环send到某一次时会出错????//sockfd=socket(AF_INET,SOCK_STREAM,0)
//new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size)long filelen=mFile.GetLength();
long lCount=filelen/sizeof(buffer);//char buffer[1024];
int iRemaining=filelen%sizeof(buffer);mFile.SeekToBegin();
ZeroMemory(buffer,sizeof(buffer));
for(long i=0;i<lCount;i++)
{
mFile.Read(buffer,sizeof(buffer));
if(send(new_fd,buffer,sizeof(buffer),0)==-1)
          {
                  errorcode;//循环到某次时send出错
           }}
mFile.Read(buffer,iRemaining);
if(send(new_fd,buffer,iRemaining,0)==-1)
{
   errorcode;
 }

解决方案 »

  1.   

    不会吧,接受端是与发送端对应的,read、send一次recv、write一次啊
      

  2.   

    除过五星高手wangjinwang讲的之外,是否需要在循环send的间隔call Sleep()一下。
    虽然我还不是很明白Sleep()的真正用途,但是看到很多例程都这么写;是否担心接收方或者gateway应付不了汹涌而来的报文风暴,丢包?
      

  3.   

    要发送的文件一次性读出来,放到一个buffer里,这样比较安全,效率还高!然后再发!如果你用的是tcp/ip,就直接发一次就行了,不用分好几次发!
      

  4.   

    这个问题我也曾遇到过,确实如王进所说的。后来在循环中加了一个sleep()后,正常了。但换了一台机器(这台机器与刚才那一台不在一个网段内)后,又出现了同样的问题,可能就是gateway的问题了,我想除了这还应有其它的原因。最保险的做法就是,自己做一个简单的协议,发送第一包后,收到对方的确认后再发送第二包。若在一定间隔内收不到确认,就重发此包。最好就是给每一个包加一个序号,这样接收方万一收到了重覆的,就丢掉,不会产生想不到的错误。
      

  5.   

    我试过了,加sleep()后可以了,但是这样对速度的影响及其明显!而若是发一个大点的文件,一次性发送肯定不实际啊!有什么好办法么?
      

  6.   

    检查send的返回值,如果是WSAEWOULDBLOCK或WSAEMSGSIZE则Sleep(20)后继续发,否则是发送失败
      

  7.   

    上面说错了,应该是检查WSAGetLastError();的返回值,给大家共享一下我的代码   Left=PackLen;
       while(Left>0)
        { SentCount = send(FSocket,(BYTE*)SendBuf+PackLen-Left,Left, 0);
          //Memo->Lines->Add("SendPack: "+IntToStr(SentCount));
          if( SentCount == SOCKET_ERROR)
            { ErrorCode = WSAGetLastError();
              if(ErrorCode != WSAEWOULDBLOCK && ErrorCode !=WSAEMSGSIZE && ErrorCode!=0)
                goto FAILED;
              if(time(NULL) > LastSentTime+20)  //20秒没发出数据
                goto FAILED;
              else
                Sleep(20);
            }
          else
           { Left-=SentCount;
             LastSentTime=time(NULL);
           }
        }
       return(true);
     FAILED:
       ShowMsgAutoClose("发送数据失败:"+SysErrorMessage(ErrorCode));
       return(false);