VC CSocket文件传送示例

来源:互联网 发布:轴承座型号查询数据 编辑:程序博客网 时间:2024/05/01 01:31

服务器端示例代码

#define PRE_AGREED_PORT      8686   //定义端口号
#define SEND_BUFFER_SIZE     4096   //buffer大小

BOOL CYourServerClass::SendFileToRemoteRecipient(CString strFileName)
{

     AfxSocketInit(NULL);
     CSocket sockSrvr;
     sockSrvr.Create(PRE_AGREED_PORT);//创建一个Sokcet并监听
     sockSrvr.Listen();//监听
     CSocket sockConnection;
     //用另一个Soket来收发数据
     sockSrvr.Accept(sockConnection);
    

     //接受从客户端发来的连接请求    
     BOOL bRet = TRUE;
    
     int fileLength, cbLeftToSend;
     BYTE* sendData = NULL;

     CFile sourceFile;
     CFileException fe;
     BOOL bFileIsOpen = FALSE;
    
     if(!(bFileIsOpen = sourceFile.Open(strFileName, CFile::modeRead | CFile::typeBinary, &fe)))
     {
         TCHAR strCause[256];
         fe.GetErrorMessage(strCause, 255);
         TRACE( "SendFileToRemoteRecipient encountered
           an error while opening the local file/n"
           "/tFile name = %s/n/tCause = %s/n/tm_cause = %d/n/tm_IOsError = %d/n",
           fe.m_strFileName, strCause, fe.m_cause, fe.m_lOsError );
        
         //在这里处理错误
         bRet = FALSE;
         goto PreReturnCleanup;
     }

     //首先发送文件长度

     fileLength = sourceFile.GetLength();
     fileLength = htonl(fileLength);

     cbLeftToSend = sizeof(fileLength);

     do
     {
         int cbBytesSent;
         BYTE* bp = (BYTE*)(&fileLength) + sizeof(fileLength) - cbLeftToSend;
         cbBytesSent = sockConnection.Send(bp, cbLeftToSend);
        
         // test for errors and get out if they occurred
         if (cbBytesSent == SOCKET_ERROR)
         {
             int iErr = ::GetLastError();
             TRACE("SendFileToRemoteRecipient returned a socket
                 error while sending file length/n"
                 "/tNumber of Bytes sent = %d/n"
                 "/tGetLastError = %d/n", cbBytesSent, iErr);
            
             //在这里处理错误

             bRet = FALSE;
             goto PreReturnCleanup;
         }
        
         cbLeftToSend -= cbBytesSent;
     }
     while ( cbLeftToSend>0 );
     //开始发送文件数据
     sendData = new BYTE[SEND_BUFFER_SIZE];    
     cbLeftToSend = sourceFile.GetLength();
    
     do
     {     
         int sendThisTime, doneSoFar, buffOffset;
        
         sendThisTime = sourceFile.Read(sendData, SEND_BUFFER_SIZE);
         buffOffset = 0;
        
         do
         {
             doneSoFar = sockConnection.Send(sendData + buffOffset, sendThisTime);
            
             //看执行是否成功
             if (doneSoFar == SOCKET_ERROR)
             {
                 int iErr = ::GetLastError();
                 TRACE( "SendFileToRemoteRecipient returned a socket error
                     while sending chunked file data/n"
                     "/tNumber of Bytes sent = %d/n"
                     "/tGetLastError = %d/n", doneSoFar, iErr );
                
                 //处理错误                
                 bRet = FALSE;
                 goto PreReturnCleanup;
             }            
            
             buffOffset += doneSoFar;
             sendThisTime -= doneSoFar;
             cbLeftToSend -= doneSoFar;
         }
         while ( sendThisTime > 0 );        
     }
     while ( cbLeftToSend > 0 );    
    
     PreReturnCleanup: // 出口点    
     delete[] sendData;    
     if ( bFileIsOpen )
         sourceFile.Close();   
    
     sockConnection.Close();    
     return bRet;

}

 

客户端示例代码

#define PRE_AGREED_PORT         8686
#define RECV_BUFFER_SIZE     4096

BOOL CYourClientClass::GetFileFromRemoteSender(CString strIP, CString fName)
{
     AfxSocketInit(NULL);
     CSocket sockClient;
     sockClient.Create();
     // PRE_AGREED_PORT 是 #define   8686
     sockClient.Connect( strIP, PRE_AGREED_PORT );
    
     //连接服务器
    
     BOOL bRet = TRUE;    
     int dataLength, cbBytesRet, cbLeftToReceive;
     BYTE* recdData = NULL;    
     CFile destFile;
     CFileException fe;
     BOOL bFileIsOpen = FALSE;    
     //打开或创建文件
    
     if(!(bFileIsOpen = destFile.Open(fName, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary, &fe)))
     {
         TCHAR strCause[256];
         fe.GetErrorMessage(strCause, 255);
         TRACE("GetFileFromRemoteSender encountered
           an error while opening the local file/n"
           "/tFile name = %s/n/tCause = %s/n/tm_cause = %d/n/tm_IOsError = %d/n",
           fe.m_strFileName, strCause, fe.m_cause, fe.m_lOsError);
        
         //在这里处理错误        
         bRet = FALSE;
         goto PreReturnCleanup;
     }   
    
     //得到文件的大小
     cbLeftToReceive = sizeof(dataLength);
    
     do
     {

         BYTE* bp = (BYTE*)(&dataLength) + sizeof(dataLength) - cbLeftToReceive;
         cbBytesRet = sockClient.Receive(bp, cbLeftToReceive);        
        
         if (cbBytesRet == SOCKET_ERROR || cbBytesRet == 0)
         {
             int iErr = ::GetLastError();
             TRACE("GetFileFromRemoteSite returned
               a socket error while getting file length/n"
               "/tNumber of Bytes received (zero means connection was closed) = %d/n"
               "/tGetLastError = %d/n", cbBytesRet, iErr);
            
             //处理错误            
             bRet = FALSE;
             goto PreReturnCleanup;
         }      
        
         cbLeftToReceive -= cbBytesRet;        
     }
     while (cbLeftToReceive > 0);

     dataLength = ntohl(dataLength);    
    
     recdData = new byte[RECV_BUFFER_SIZE];
     cbLeftToReceive = dataLength;
    
     do
     {    
         int iiGet, iiRecd;

         iiGet = (cbLeftToReceive<RECV_BUFFER_SIZE) ? cbLeftToReceive : RECV_BUFFER_SIZE;
         iiRecd = sockClient.Receive(recdData, iiGet);

    
         if (iiRecd == SOCKET_ERROR || iiRecd == 0)
         {
             int iErr = ::GetLastError();
             TRACE("GetFileFromRemoteSite returned a socket error
                 while getting chunked file data/n"
                 "/tNumber of Bytes received (zero means connection was closed) = %d/n"
                 "/tGetLastError = %d/n", iiRecd, iErr);
            
             //要在这里处理错误            
             bRet = FALSE;
             goto PreReturnCleanup;
         }

        
         destFile.Write( recdData, iiRecd); // 写入数据
         cbLeftToReceive -= iiRecd;

     }
     while ( cbLeftToReceive > 0 );

     PreReturnCleanup: // 入口点
    
     delete[] recdData;        
    
     if ( bFileIsOpen )
         destFile.Close();

    
     sockClient.Close();
    
     return bRet;
}

 

 

ZZ:http://blog.sina.com.cn/s/blog_554b1f1b0100bp1p.html