VC+CSocket文件传送示例

简介:

服务器端示例代码

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

BOOL CYourServerClass::SendFileToRemoteRecipient(CString fName)
{
    
    

     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( fName, 
            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;
}

本文转自博客园知识天地的博客,原文链接:VC+CSocket文件传送示例,如需转载请自行联系原博主。


相关文章
VC通过函数名调用DLL的标准范例
VC通过函数名调用DLL的标准范例
70 0
|
C++ 索引
VC通过函数索引调用DLL范例
VC通过函数索引调用DLL范例
63 0
|
并行计算
西门子Prodave5.5使用说明及VC示例
西门子PLC的通信协议主要是PPI、MPI、Profibus、CP243/CP343/CP443 网络协议,prodave是早期完成的程序接口,除了网络协议外其它的主要协议都支持
1021 0
|
安全 编译器 C语言