现在要做一个文件上传的程序,分为服务器端和客户器端,服务器端要同时支持多个客户,基于TCP协议,
大文件需要进行文件分割,请问应该如何实现,有原码更佳
我的Email:[email protected]
由于我上网不方便,所以请大家帮忙UP一下,3ks

解决方案 »

  1.   

    有好多FTP工具,可以拿过来用。我自己编了一个类,可以实现文件传送,不过是基于UDP的
      

  2.   

    因为我的程序需要和服务器端进行交互,所以fTP不够用,只好用Socket写基于TCP协议的程序,请大家帮忙
      

  3.   

    void YourSend()
    {
    AfxSocketInit(NULL);
    CSocket sockClient;
             sockClient.Create();
             sockClient.Connect(hostip, PORT); 
    CFile myFile;
    if(!myFile.Open(strFilename, CFile::modeRead | CFile::typeBinary))
    return FALSE;
    nameLength=strlen(strFilename)+1;
    sockClient.Send(&nameLength,4);
    char* filename=new char[nameLength];
             sockClient.Send(strFilename,nameLength);
             int myFileLength = myFile.GetLength(); // Going to send the   sockClient.Send(&myFileLength, 4); // 4 bytes long
    byte* data = new byte[myFileLength]; 
    myFile.Read(data, myFileLength);
    sockClient.Send(data, myFileLength); //Send the whole thing now
    myFile.Close();
    sockClient.Close();
    delete data;
    return TRUE;
    }
    ////////////////
    接受端使用异步套接字,在此之前创建监听套节字。
    void CXXXSocket::OnReceive()
    {
    int dataLength(0); int nameLength(0);
    Receive(&nameLength, 4);
    char* filename=new char[nameLength];
    Receive(filename,nameLength);//get file name
    Receive(&dataLength, 4); //Now we get the File Size first
    byte* data = new byte[dataLength];
    Receive(data, dataLength); //Get the whole thing
    CFile destFile(filename, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary); destFile.Write(data, dataLength); // Write it
             destFile.Close();
             delete data;
    delete filename;
    AsyncSelect(FD_CONNECT|FD_READ);
    }
      

  4.   

    到http://www.vckbase.com
    或http://www.vchelp.net/vchelp/vchelp.asp
    应有类似的代码或文章的。
      

  5.   

    发送:
    #include "afxmt.h"
    CString m_PATH;
    DWORD filesize;
    HWND hwnd_p;
    int IsBegin;
    void CNetSendDlg::OnTransfer(CString m_PATH)
    {}UINT CNetSendDlg::ThreadA(LPVOID pParam)
    {
        IsBegin=0;
        CFile myFile;
        if(!myFile.Open(m_PATH, CFile::modeRead | CFile::typeBinary|CFile::shareDenyNone))
        {
            return 0;
        }    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,20);
        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             FindFileData;
        FindClose(FindFirstFile(m_PATH,&FindFileData));
          send(sockRecv,(char*)&FindFileData,sizeof(WIN32_FIND_DATA),0);
        ////////////////////////////////////////////////////////
        //PROGRESS
        filesize=(short)FindFileData.nFileSizeLow; 
        ::PostMessage(hwnd_p,WM_USER_PROG,NULL,NULL);
        ////////////////////////////////////////////////////
        UINT dwRead=0;
        byte* data;
        while(dwRead<FindFileData.nFileSizeLow)
        {
            data = new byte[2048];
            UINT dw=myFile.Read(data, 2048);
            send(sockRecv,(char*)data,2048,0);
            dwRead+=dw;
            delete [] data;
            IsBegin=1;
            ::PostMessage(hwnd_p,WM_USER_PROG,NULL,NULL);
        }
        IsBegin=2;
        //::PostMessage(hwnd_p,WM_USER_PROG,NULL,NULL);    myFile.Close();
        closesocket(sockRecv);
        closesocket(sockSrvr);
        WSACleanup();    return 0;
    }LRESULT CNetSendDlg::OnProgress(WPARAM wParam, LPARAM lParam)
    {
        CString st;
        st.Format("%d",filesize);    if(IsBegin==0)
        {
        m_Progress.SetRange(0,(short)filesize/1000); 
        m_Progress.SetPos(0);
        m_Progress.SetStep(1);
        }
        else if(IsBegin==1)
        {
        m_Progress.StepIt();
        }
        else if(IsBegin==2)
        {
            m_Progress.SetPos((short)filesize/1000);
        }    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       = "*.txt\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("txt") ;
        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() 
    {
    //    m_PATH="c:\\1.jpg";
        GetDlgItem(IDC_EDIT1)->GetWindowText(m_PATH);    hwnd_p=this->m_hWnd;
        AfxBeginThread(ThreadA,NULL,THREAD_PRIORITY_IDLE);
    }
      

  6.   

    接收
    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 version is incorrect!");
            WSACleanup();
            return;
        }
        
        if ((sockClient = socket (PF_INET, SOCK_STREAM, IPPROTO_IP)) == INVALID_SOCKET)
        {
            AfxMessageBox("Create socket error!");
            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,(short)fd.nFileSizeLow); 
            m_Progress.SetPos(0);
            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((short)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();
        }
    }
      

  7.   

    最用用C++版的,不要用什么MFC的CSocket
      

  8.   

    我当前的处理方式大致如下:在服务器端采用消息机制进行接收
    void CServerDlg::OnServerSock(WPARAM wParam,LPARAM lParam)
    {
         switch(lParam)
         {
    case FD_ACCEPT:
            case FD_READ:
                 if(Filelen<0) break; //Filelen为文件的总长度
         char m_buf[SIZE]; //SIZE为每次定义的传输长度
         long len2=Filelen>SIZE?SIZE:Filelen;
         long len1=recv((SOCKET)wParam,m_buf,len2,0);
         if(len1<0)break;
         destFile.Write(m_buf, len1); //destFile为目标文件
         Filelen=Filelen-SIZE;
     
            ...
         }

    在客户机端
    CFile myFile;
    myFile.Open(strFileName, CFile::modeRead | CFile::typeBinary|CFile::shareDenyNone); 
    long minuslen=myFile.GetLength();
    long sendlen;
    char m_buf[SIZE];
    while(minuslen>0)
    {
         sendlen=minuslen>SIZE?SIZE:minuslen;
         myFile.Read(m_buf, sendlen);
         bool m_bSuccess=false;
         while(!m_bSuccess)
         {
    if(send(m_SocketClient,m_buf,sendlen,0)!=SOCKET_ERROR)
      m_bSuccess=true;
         }

    }
    myFile.Close(); 现在的问题是,当客户端发送完成之后,服务器端只能收到部分的数据,难道服务器端采用消息机制在这种情况下不能使用,可是我还需要
    进行其他信息的传送控制(上传文件只是其中的一项功能),我该怎么做???请大虾们救救我吧