void serverStatr(int iPort)
{
WSADATA wsaData;
SOCKET m_ListenSock;
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)//winsock打开
{

MessageBox(NULL,_T("开启sock错误"),_T("error"),0);
return ;
}
m_ListenSock=socket(AF_INET , SOCK_STREAM , IPPROTO_TCP);
if(m_ListenSock==INVALID_SOCKET)
{
MessageBox(NULL,_T("新建Socket失败!"),_T("ERROR"),0);
return;
}
if ( iPort <= 0 || iPort > 65535 ) {
MessageBox(NULL,_T("请输入合适的端口:1 - 65535",),_T("ERROR"),0);
goto __Error_End;
} sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = INADDR_ANY;
service.sin_port = htons(iPort); if(bind(m_ListenSock,(sockaddr*)&service,sizeof(sockaddr_in))==SOCKET_ERROR)
{
MessageBox(NULL,_T("绑定端口失败!"),_T("ERROR"),0);
goto __Error_End;
}
if(listen(m_ListenSock,5)==SOCKET_ERROR)
{
MessageBox(NULL,_T("监听失败"),_T("ERROR"),0);
goto __Error_End;
}
while(true)
{
if(SOCKET_Select(m_ListenSock,100,true))
{
sockaddr_in clientAddr;
int iLen=sizeof(sockaddr_in);
SOCKET accSock=accept(m_ListenSock,(struct sockaddr*)&clientAddr,&iLen);
if(accSock==INVALID_SOCKET)
{
continue;
}

char szBuf[1024];
FILE *pWrite;
memset(szBuf,0,sizeof(szBuf));
    int iOpen=1;
 pWrite=fopen("2.osg","wb+");
while(recv(accSock,szBuf,MAX_BUF_SIZE,0))
{
if(iOpen==1)
{
   pWrite=fopen(szBuf,"wb+");
   iOpen=0;
   std::cout<<"name:"<<szBuf<<endl<<"Start";
   continue;
}
if(iOpen==0)
{
    if(strcmp(szBuf,"END")!=0)
                  {
 
        fwrite(szBuf,1024,1,pWrite);
                      memset(szBuf,0,sizeof(szBuf));
  
                  }
    else if(strcmp(szBuf,"END")==0)
    {
     fclose(pWrite);
     iOpen=1;
 std::cout<<"End"<<endl;
    }
} }

Sleep(1000);
}
} __Error_End:
    closesocket(m_ListenSock);
return;
}
上面的是服务器端的代码,用来接受从客户端传来的文件。void SendData(char* path)
{
  FILE*   fpRead;     
     fpRead=fopen(path,"rb+"); 
 memset(szBuf,0,sizeof(szBuf));
 strcpy(szBuf,path);
 send(client,szBuf,sizeof(szBuf),0);
  memset(szBuf,0,sizeof(szBuf));
      while(!feof(fpRead))   
       {   
           fread(szBuf,1024,1,fpRead);   
           int isend=0;
       isend=send(client,szBuf,sizeof(szBuf),0);
       if(isend==SOCKET_ERROR || isend==0)
         {
          MessageBox(NULL,_T("发送错误"),_T("ERROR"),0);
           closesocket(client);
           return;
            }
       }
  fclose(fpRead);  memset(szBuf,0,sizeof(szBuf));
 strcpy(szBuf,"END");std::cout<<szBuf;
 send(client,szBuf,sizeof(szBuf),0);
}这个是发送数据的函数。
好像这个函数一直再发送数据,接收端接受到的数据要比发送的文件大。请问一下哪里出问题了

解决方案 »

  1.   

     memset(szBuf,0,sizeof(szBuf));
          while(!feof(fpRead))   
           {   
               fread(szBuf,1024,1,fpRead);   
               int isend=0;
               isend=send(client,szBuf,sizeof(szBuf),0);
               if(isend==SOCKET_ERROR || isend==0)
                 {
                     MessageBox(NULL,_T("发送错误"),_T("ERROR"),0);
                   closesocket(client);
                   return;
                   }
           }
    ============
    这一段有问题,你应该在循环内部调用memset(szBuf,0,sizeof(szBuf));
    否则,你发送的数据必然是1024的倍数。因为在读取到文件尾时,其实你的fread(szBuf,1024,1,fpRead);   语句是不能将szBuf填满的,但由于你循环内部没有将szBuf清空,所以最后一次读取时,不足的部分仍然保留了前一次的数据,自然出现大小不一致的情况。大小差应该在1024以内。
    =======修改:
          while(!feof(fpRead))   
           {   
               memset(szBuf,0,sizeof(szBuf));
               fread(szBuf,1024,1,fpRead);   
               int isend=0;
               isend=send(client,szBuf,sizeof(szBuf),0);
               if(isend==SOCKET_ERROR || isend==0)
                 {
                     MessageBox(NULL,_T("发送错误"),_T("ERROR"),0);
                   closesocket(client);
                   return;
                   }
           }
      

  2.   

    还有一个问题,当出现isend为0或者SOCKET_ERROR时,最后你应该用break,而不是return,否则fpRead指针就没法关闭了。
      

  3.   

    谢谢。我按照您说的修改了。但是问题还是没解决。
    int _tmain(int argc, _TCHAR* argv[])
    {

    Connector("192.168.1.105",5000);
    SendData("e:/2.osg");
    Sleep(5000);
    CloseConnect();
    return 0;
    }
    如果我不closeConnect();接收端会提示无限的接收“Name”和“End”。  while(recv(accSock,szBuf,MAX_BUF_SIZE,0))
                {
                    if(iOpen==1)
                    {
                       pWrite=fopen(szBuf,"wb+");
                       iOpen=0;
                       std::cout<<"name:"<<szBuf<<endl<<"Start";
                       continue;
                    }
                    if(iOpen==0)
                    {
                        if(strcmp(szBuf,"END")!=0)
                      {
                     
                            fwrite(szBuf,1024,1,pWrite);
                          memset(szBuf,0,sizeof(szBuf));
                      
                      }
                        else if(strcmp(szBuf,"END")==0)
                        {
                             fclose(pWrite);
                             iOpen=1;
                             std::cout<<"End"<<endl;
                        }
                    }
      

  4.   

    else if(strcmp(szBuf,"END")==0)
    ==这什么意思啊???要求szBuf正好是END么?szBuf可是个1024字节的数据啊......
      

  5.   

    StartEnd
    name:End
    StartEnd
    name:End
    StartEnd
    name:End
    StartEnd
    name:End
    StartEnd
    name:End
    StartEnd
    name:End
    StartEnd
    name:End
    一直这样循环输出
      

  6.   

    发送端发送完一个文件后发一个End用来让接收端判断是否接受完毕。
    End只占了3哥字节哦,那是得取出前3个字节来比较?
      

  7.   

    发送端发送完一个文件后发一个End用来让接收端判断是否接受完毕。 
    End只占了3哥字节哦,那是得取出前3个字节来比较? 
      

  8.   

    越来越不明白你的问题了。能不能说全一点。
    你的SendData函数到底怎么调用的?接收端反复收到数据,那自然是因为服务端发了才会这样。既然能收到END,说明SendData函数不是个死循环,那么就是SendData函数被死循环调用了。
      

  9.   

    现在的问题就是接收到的文件的大小每次都不一样。我是用发送端发送“END”来标石一个文件发送结束。当接收端收到“END后”,关闭写指针。
    可是现在当发送端退出程序后,接收端还在一直接收END。
      

  10.   

    不是在一直接收end,而是你这段代码有问题
    while(recv(accSock,szBuf,MAX_BUF_SIZE,0))
                {
                    if(iOpen==1)
                    {
                       pWrite=fopen(szBuf,"wb+");
                       iOpen=0;
                       std::cout<<"name:"<<szBuf<<endl<<"Start";
                       continue;
                    }
                    if(iOpen==0)
                    {
                        if(strcmp(szBuf,"END")!=0)
                      {
                     
                            fwrite(szBuf,1024,1,pWrite);
                          memset(szBuf,0,sizeof(szBuf));
                      
                      }
                        else if(strcmp(szBuf,"END")==0)
                        {
                             fclose(pWrite);
                             iOpen=1;
                             std::cout<<"End"<<endl;
                        }
                    }
    你在整个循环中,你只在收到非END数据时,进行memset(szBuf,0,sizeof(szBuf))操作,而当收到END时,你没有做这个操作,导致szBuf中一直保存着END这个值。当服务端关闭时,recv函数返回的是-1,而不是你期望的0,因此while条件始终成立。就是这样。你的代码很不严谨。
      

  11.   


    谢谢鹦鹉这么耐心。我改了下代码while(true)
    {
    memset(szBuf,0,sizeof(szBuf));
    int iRet=recv(accSock,szBuf,MAX_BUF_SIZE,0);
    if(iRet>0)
    {
    if(iOpen==1)
    {
    pWrite=fopen(szBuf,"wb+");
    iOpen=0;
    std::cout<<"name:"<<szBuf<<endl<<"Start";
    continue;
    }
    if(iOpen==0)
    {
    if(strcmp(szBuf,"END")!=0)
    {
    fwrite(szBuf,1024,1,pWrite);
    }
    else if(strcmp(szBuf,"END")==0)
    {
    fclose(pWrite);
    iOpen=1;
    std::cout<<"End"<<endl;
        }
    }
    }
    else
    {
    closesocket(m_ListenSock);
    break;
    } }
    为什么在一台机器上运行没问题。在局域网中,接收到的文件就有问题。。
      

  12.   

    不知道你具体的问题是什么。但是,你的代码总是不严谨。这一段:
     if(iOpen==0)
                        {
                            if(strcmp(szBuf,"END")!=0)
                            {
                                fwrite(szBuf,1024,1,pWrite);
                            }
                            else if(strcmp(szBuf,"END")==0)
                            {
                                fclose(pWrite);
                                iOpen=1;
                                std::cout<<"End"<<endl;
                            }
                        }
    其实是有问题的,fwrite(szBuf,1024,1,pWrite);是不合理的。你怎么肯定每次都是1024呢?文件的最后一部分谁能保证正好1024呢?你应该用iRet替代1024,iRet才代表实际收到的字节数。
      

  13.   

    解决得,问题处在发送上面, fread(szBuf,1024,1,fpRead);   
               int isend=0;
               isend=send(client,szBuf,sizeof(szBuf),0);
    改为 int iRed=fread(szBuf,1,1024,fpRead);   
               int isend=0;
               isend=send(client,szBuf,iRed,0);基础不扎实啊。而且好多时候总是按照自己的想法来。
    谢谢鹦鹉兄一直耐心的帮助我。谢谢