在winsock下,有时由于数据包过大,往往一次发送和接收不能把数据包完整的完。我自己做了一个发送和接收的函数,总是有问题,那位大侠有处理的函数,请贴出来,如果能够执行必将再送高分。

解决方案 »

  1.   

    发送:#include "afxmt.h"
    CString m_PATH;
    UINT CNetSendDlg::ThreadA(LPVOID pParam)
    {
    CString szIP;
    struct sockaddr_in sin;
    WSADATA wsaData;    
    SOCKET sockSrvr,sockRecv;
    char *IpAddr;
    if(WSAStartup(0x0101, &wsaData ))
    {
    AfxMessageBox("初始化 TCP/IP 协议栈发生错误!");
    return 0;
    }
    if(wsaData.wVersion != 0x0101)
    {
    AfxMessageBox("Winsock version is incorrect!");
    WSACleanup();
    return 0;
    }

    if ((sockSrvr = socket (PF_INET, SOCK_STREAM, IPPROTO_IP)) == INVALID_SOCKET)
    {
    AfxMessageBox("Create socket error!");
    return 0;
    } if ((sockRecv = socket (PF_INET, SOCK_STREAM, IPPROTO_IP)) == INVALID_SOCKET)
    {
    AfxMessageBox("Create socket error!");
    return 0;
    }
    //////////////////////////////////////
      CString m_addr;
      CString m_strT;
      CString sNetBiosName;
      char hostname[128];
      struct hostent *phost;
      gethostname(hostname,128);
      m_addr = hostname;
      phost = gethostbyname(hostname);
      int m_iCounter=0;
      for(int j = 0;j<4;j++)
      {
      
      m_strT.Format("%u", (unsigned int)((unsigned char*)phost->h_addr_list[0])[j]);
      sNetBiosName+=m_strT;
      if(m_iCounter<3)
      {
      m_iCounter++;
      sNetBiosName+=".";
      }  
      }
    //////////////////////////////////////
    szIP=sNetBiosName;
    IpAddr=szIP.GetBuffer(szIP.GetLength());
        sin.sin_family=AF_INET;
    sin.sin_addr.s_addr=inet_addr(IpAddr);
    sin.sin_port=htons(800);
    if(bind(sockSrvr,(sockaddr*)&sin,sizeof(sin))<0)
    {
    AfxMessageBox("绑定错误");
    return 0;
    }
    listen(sockSrvr,5);
    int length=sizeof(sin);
    sockRecv=accept(sockSrvr,(struct sockaddr*)&sin,&length);

    int timeout=300; 
    int status=setsockopt(sockRecv,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));
    if(status)
    {
    AfxMessageBox("设置超时错误");
    WSACleanup();
    return 0;
    }
    int buf=10240;
        int status2=setsockopt(sockRecv,SOL_SOCKET,SO_RCVBUF,(char*)&buf,sizeof(int));
    if(status2)
    {
    AfxMessageBox("设置缓冲区大小错误");
    WSACleanup();
    return 0;
    }
    //////////////////////////////////////////////////////////////////
    WIN32_FIND_DATA             fd;
    FindClose(FindFirstFile(m_PATH,&fd));
    send(sockRecv,(char*)&fd,sizeof(WIN32_FIND_DATA),0); ////////////////////////////////////////////////////
    CFile myFile;
    if(!myFile.Open(m_PATH, CFile::modeRead | CFile::typeBinary|CFile::shareDenyNone))
    {
    return 0;
    } UINT dwRead=0;
    byte* data;
    while(dwRead<fd.nFileSizeLow)
    {
    data = new byte[2048];
    UINT dw=myFile.Read(data, 2048);
    send(sockRecv,(char*)data,2048,0);
    dwRead+=dw;
    delete [] data; } myFile.Close();
    closesocket(sockRecv);
    closesocket(sockSrvr);
    WSACleanup(); return 0;
    }
    static char BASED_CODE szFilter[]="|*.*|";
    void CNetSendDlg::OnButton1() 
    {
    OPENFILENAME ofn ;
    TCHAR  szFullName[_MAX_PATH];
    ::ZeroMemory (&ofn, sizeof(OPENFILENAME)) ;
    szFullName[0] = TEXT('\0') ;
    ofn.lStructSize       = sizeof (OPENFILENAME) ;
        ofn.hwndOwner         = m_hWnd;
        ofn.hInstance         = NULL ;
        ofn.lpstrFilter       = "*.*\0\0" ;
        ofn.lpstrCustomFilter = NULL ;
        ofn.nMaxCustFilter    = 0 ;
        ofn.nFilterIndex      = 0 ;
        ofn.nMaxFile          = MAX_PATH ;
        ofn.nMaxFileTitle     = MAX_PATH ;
        ofn.lpstrInitialDir   = "c:\\" ;
        ofn.lpstrTitle        = "保存到";
    ofn.lpstrFile   = szFullName ;
        ofn.nFileExtension    = 0 ;
        ofn.lpstrDefExt       = TEXT("*") ;
        ofn.lCustData         = 0 ;
        ofn.lpfnHook          = NULL ;
        ofn.lpTemplateName    = NULL ;
        ofn.Flags             = OFN_ENABLESIZING | OFN_OVERWRITEPROMPT ;
        

    if(!::GetOpenFileName(&ofn))
    return;
      GetDlgItem(IDC_EDIT1)->SetWindowText(ofn.lpstrFile);

    }void CNetSendDlg::OnButton2() 
    {
    GetDlgItem(IDC_EDIT1)->GetWindowText(m_PATH);
    AfxBeginThread(ThreadA,this,THREAD_PRIORITY_IDLE);
    }void CNetSendDlg::OnRec() 
    {
    CString szIP;
    GetDlgItem(IDC_EDIT2)->GetWindowText(szIP);
    struct sockaddr_in sin;
    WSADATA wsaData;    
    SOCKET sockClient;
    int IpPort;
    char *IpAddr;
    IpAddr=szIP.GetBuffer(szIP.GetLength());
    IpPort=800;

    if(WSAStartup(0x0101, &wsaData ))
    {
    AfxMessageBox("初始化 TCP/IP 协议栈发生错误!");
    return;
    }
    if(wsaData.wVersion != 0x0101)
    {
    AfxMessageBox("Winsock版本不正确!");
    WSACleanup();
    return;
    }

    if ((sockClient = socket (PF_INET, SOCK_STREAM, IPPROTO_IP)) == INVALID_SOCKET)
    {
    AfxMessageBox("创建socket错误!");
    return;
    }


    sin.sin_family=AF_INET;
    sin.sin_addr.s_addr=inet_addr(IpAddr);
    sin.sin_port=htons((short)IpPort);


    int timeout=300; 
    int status=setsockopt(sockClient,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));
    if(status)
    {
    MessageBox("设置超时错误");
    WSACleanup();
    return ;
    }
    int buf=10240;
        int status2=setsockopt(sockClient,SOL_SOCKET,SO_RCVBUF,(char*)&buf,sizeof(int));
    if(status2)
    {
    MessageBox("设置缓冲区大小错误");
    WSACleanup();
    return ;
    }


    if(connect (sockClient, (struct sockaddr *)&sin, sizeof (sin)) == SOCKET_ERROR)
    {
    MessageBox("连接错误");
    closesocket(sockClient);
    WSACleanup();
    return;
    } WIN32_FIND_DATA fd;
    recv(sockClient,(char*)&fd,sizeof(WIN32_FIND_DATA),0); m_Progress2.SetRange(0,fd.nFileSizeLow/2048); 
    m_Progress2.SetStep(1); CString m_ProDir="e:\\";
    CFile destFile(m_ProDir+fd.cFileName, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);
    UINT dwRead = 0;
    while(dwRead<fd.nFileSizeLow)
    {
    byte* data = new byte[2048];
    memset(data,0,2048);
        UINT dw=recv(sockClient,(char*)data,2048,0);
    destFile.Write(data, dw);
    dwRead+=dw;
    delete [] data;
    m_Progress2.StepIt();
    }
    m_Progress2.SetPos(fd.nFileSizeLow); 
    m_Progress2.SetPos(0);
    SetFileTime((HANDLE)destFile.m_hFile,&fd.ftCreationTime,
    &fd.ftLastAccessTime,&fd.ftLastWriteTime);
    SetFileAttributes(m_ProDir+fd.cFileName,fd.dwFileAttributes);
    destFile.Close();
    closesocket (sockClient);
         WSACleanup();

    }
      

  2.   

    接收:void CNetRecvDlg::OnButton1() 
    {
    CString szIP;
    GetDlgItem(IDC_EDIT1)->GetWindowText(szIP);
    struct sockaddr_in sin;
    WSADATA wsaData;    
    SOCKET sockClient;
    int IpPort;
    char *IpAddr;
    IpAddr=szIP.GetBuffer(szIP.GetLength());
    IpPort=800;

    if(WSAStartup(0x0101, &wsaData ))
    {
    AfxMessageBox("初始化 TCP/IP 协议栈发生错误!");
    return;
    }
    if(wsaData.wVersion != 0x0101)
    {
    AfxMessageBox("Winsock版本不正确!");
    WSACleanup();
    return;
    }

    if ((sockClient = socket (PF_INET, SOCK_STREAM, IPPROTO_IP)) == INVALID_SOCKET)
    {
    AfxMessageBox("创建socket错误!");
    return;
    }


    sin.sin_family=AF_INET;
    sin.sin_addr.s_addr=inet_addr(IpAddr);
    sin.sin_port=htons((short)IpPort);


    int timeout=300; 
    int status=setsockopt(sockClient,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));
    if(status)
    {
    MessageBox("设置超时错误");
    WSACleanup();
    return ;
    }
    int buf=10240;
        int status2=setsockopt(sockClient,SOL_SOCKET,SO_RCVBUF,(char*)&buf,sizeof(int));
    if(status2)
    {
    MessageBox("设置缓冲区大小错误");
    WSACleanup();
    return ;
    }


    if(connect (sockClient, (struct sockaddr *)&sin, sizeof (sin)) == SOCKET_ERROR)
    {
    MessageBox("连接错误");
    closesocket(sockClient);
    WSACleanup();
    return;
    }
    else{
    WIN32_FIND_DATA fd;
    ::Sleep(20);
    recv(sockClient,(char*)&fd,sizeof(WIN32_FIND_DATA),0);
    ////////////////////////////////////////////////////////
    //PROGRESS
    m_Progress.SetRange(0,fd.nFileSizeLow/2048); 
    m_Progress.SetStep(1);
            ////////////////////////////////////////////////////
    CString m_ProDir="e:\\";
    CFile destFile(m_ProDir+fd.cFileName, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);
    UINT dwRead = 0;
    while(dwRead<fd.nFileSizeLow)
    {
    byte* data = new byte[2048];
    memset(data,0,2048);
        UINT dw=recv(sockClient,(char*)data,2048,0);
    destFile.Write(data, dw);
    dwRead+=dw;
    delete [] data;
    m_Progress.StepIt();
    }
    m_Progress.SetPos(fd.nFileSizeLow); 
    SetFileTime((HANDLE)destFile.m_hFile,&fd.ftCreationTime,
    &fd.ftLastAccessTime,&fd.ftLastWriteTime);
    SetFileAttributes(m_ProDir+fd.cFileName,fd.dwFileAttributes);
    destFile.Close();
    closesocket (sockClient);
    WSACleanup();
    }
    }