TCP发送文件(转)

    技术2025-06-01  13

    001 //文件传送线程//服务器发送文件,客户端发送文件消息 002 UINT threadSendFile( LPVOID pvar) 003 { 004      CDlgSendMessage *pDlg = (CDlgSendMessage *) pvar; 005   006 CFile m_fSendfile; 007 m_fSendfile.Close(); 008   009 if (!m_fSendfile.Open(pDlg->m_sendfilepath, CFile::modeRead | CFile::typeBinary)) 010 { 011     AfxMessageBox( "打开文件失败!" ); 012     return false ; 013 } 014   015   016 SOCKET sSendMsg; //客户端套接字 017 SOCKADDR_IN inetAddr; 018 sSendMsg = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); 019   020 if (INVALID_SOCKET == sSendMsg) 021 { 022     AfxMessageBox( "创建客户端发送套接字失败!" ); 023     m_fSendfile.Close(); 024     return 0; 025 } 026   027 inetAddr.sin_family = AF_INET; 028 inetAddr.sin_port = htons(PUB_MSG_PORT); 029 inetAddr.sin_addr.s_addr= inet_addr(pDlg->m_receiveip); //为接受文件者IP 030   031   032   033      034 if (SOCKET_ERROR == connect(sSendMsg, (SOCKADDR *)&inetAddr, sizeof (SOCKADDR_IN))) //为接受文件者 035 { 036   037             038       AfxMessageBox( "对方不在线,不存在监听套接字失败!" ); 039     closesocket(sSendMsg); 040     m_fSendfile.Close(); 041     return 0; 042 } 043   044 char buff[MAX_BUF_SIZE] = "" ; 045 CString strMsgSend( "1001/" ); 046 CString strSize; 047   048 //计算文件大小 049 if (pDlg->m_fiSendFile.nFileSizeLow / (1024 * 1024) != 0) 050 { 051     strSize.Format( "%.2fMB" , pDlg->m_fiSendFile.nFileSizeLow / (1024.0 * 1024)); 052 } 053 else 054 { 055     strSize.Format( "%.2fKB" , pDlg->m_fiSendFile.nFileSizeLow / (1024.0)); 056 } 057   058 memcpy (buff, pDlg->m_fiSendFile.szFileTitle, sizeof (pDlg->m_fiSendFile.szFileTitle)); 059 strMsgSend += buff; 060 strMsgSend += "/" ; 061 strMsgSend += strSize; 062 strMsgSend += "/" ; 063 //发送文件标题,文件大小//作为客户端发消息和接受套接字 064   065   066 if (SOCKET_ERROR == send(sSendMsg, strMsgSend.GetBuffer(0), strMsgSend.GetLength(), 0)) 067 { 068     AfxMessageBox( "发送消息失败!: threadSendFile" ); 069     closesocket(sSendMsg); 070     m_fSendfile.Close(); 071     return 0; 072 } 073   074 memset (buff, 0, MAX_BUF_SIZE); 075   076   077 if (SOCKET_ERROR == recv(sSendMsg, buff, MAX_BUF_SIZE, 0)) //收到对方反馈信息//收到同意接受信息 078 { 079     AfxMessageBox( "接收消息失败!: threadSendFile" ); 080     closesocket(sSendMsg); 081     m_fSendfile.Close(); 082     return 0; 083 } 084   085   086 //解析对方的确认信息 087 CString strCmd; 088 strCmd += buff; 089 strCmd = strCmd.Left(4); 090 int iCmd = -1; 091 iCmd = atoi (strCmd); 092 if (MSG_ACCEPT != iCmd) 093 { 094     AfxMessageBox( "对方拒绝接收文件!: threadSendFile" ); 095     closesocket(sSendMsg); 096     m_fSendfile.Close(); 097   098     return false ; // 099 } 100   101 //对方同意接收文件,开始发送 102   103   104 //创建服务器 发送文件socket, 打开FILE_PORT 105 SOCKET sSendFile; //监听套接字 106 SOCKET sAccept; //发送接受套接字 107 SOCKADDR_IN inetAddrSendFile; 108 SOCKADDR_IN inetAddrAccept; 109   110 sSendFile = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); 111 if (INVALID_SOCKET == sSendFile) 112 { 113     AfxMessageBox( "创建套接字错误!: threadSendFile" ); 114     closesocket(sSendMsg); 115       m_fSendfile.Close(); 116     return 0; 117 } 118   119 inetAddrSendFile.sin_addr.s_addr = htonl(INADDR_ANY); 120 inetAddrSendFile.sin_port    = htons(PUB_FILE_PORT); 121 inetAddrSendFile.sin_family    = AF_INET; 122   123 if (SOCKET_ERROR == bind(sSendFile, (SOCKADDR *)&inetAddrSendFile, sizeof (SOCKADDR))) 124 { 125     AfxMessageBox( "绑定套接字错误!: threadSendFile" ); 126     closesocket(sSendMsg); 127     closesocket(sSendFile); 128     m_fSendfile.Close(); 129     return 0; 130 } 131   132 if (SOCKET_ERROR == listen(sSendFile, 5)) 133 { 134     AfxMessageBox( "监听错误!: threadSendFile" ); 135     closesocket(sSendMsg); 136     closesocket(sSendFile); 137     m_fSendfile.Close(); 138     return 0; 139 } 140   141 int iLen = sizeof (SOCKADDR); 142 sAccept = accept(sSendFile, (SOCKADDR *)&inetAddrAccept, &iLen); 143   144 if (INVALID_SOCKET == sAccept) 145 { 146     AfxMessageBox( "accept socket error occurred!: threadSendFile" ); 147     closesocket(sSendMsg); 148     closesocket(sSendFile); 149     m_fSendfile.Close(); 150     return 0; 151 } 152   153 //发送文件信息给对方 154 char buffInfo[MAX_BUF_SIZE] = "" ; 155 memcpy (buffInfo, &pDlg->m_fiSendFile, sizeof (pDlg->m_fiSendFile)); 156 send(sAccept, buffInfo, sizeof (pDlg->m_fiSendFile), 0); 157 memset (buffInfo, 0, MAX_BUF_SIZE); 158   159 //对方同意接收huozebujieshou,开始传送 160       161      recv(sAccept, buffInfo, MAX_BUF_SIZE, 0); //对方不保持就不往下走 162   163 //循环发送文件 164 DWORD dwRead = 0; 165 DWORD dwCurrentRead = 0; 166 BYTE *bReadBuff = new BYTE [MAX_BUF_SIZE]; 167   168 //设置发送进度 169   170   171 while (dwRead < pDlg->m_fiSendFile.nFileSizeLow) 172 { 173     dwCurrentRead = 0; 174     memset (bReadBuff, 0, MAX_BUF_SIZE); 175     dwCurrentRead = m_fSendfile.Read(bReadBuff, MAX_BUF_SIZE); //读数据到缓冲区 176     if (SOCKET_ERROR == send(sAccept, ( char *)bReadBuff, dwCurrentRead, 0)) //发送数据 177     { 178      AfxMessageBox( "文件发送中断!: threadSendFile" ); //如果对方取消持,发送方也也一直往下走 179      closesocket(sSendMsg); 180      closesocket(sSendFile); 181      m_fSendfile.Close(); 182      break ; 183     } 184   185     dwRead += dwCurrentRead; //已经发送数据 186      CString   str;   187          str.Format( "%d" ,   dwRead); 188     AfxMessageBox( "已经发送" +str); 189   190 } 191 AfxMessageBox( "发送完成" ); 192 delete bReadBuff; //释放堆内存 193 //结束时处理 194 m_fSendfile.Close(); //文件关闭 195 if (INVALID_SOCKET != sAccept) 196 { 197     closesocket(sAccept); //关闭接受套接字 198 } 199 if (INVALID_SOCKET != sSendFile) 200 { 201     closesocket(sSendFile); //关闭发送套接字 202 } 203   204   205 AfxEndThread(0); 206   207 return 1; 208 } 209   210 //客户端文件接收线程 211 UINT threadRecvFile( LPVOID pvar) 212 { 213   214      char * m_sip=( char *)pvar; 215 SOCKET sFileRecv; 216 SOCKADDR_IN inetAddr; 217   218 //新建一个客户socket,连接文件 发送方服务器 接收文件 219 sFileRecv = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); 220 if (INVALID_SOCKET == sFileRecv) 221 { 222     AfxMessageBox( "创建套接字失败 : threadRecvFile" ); 223     AfxEndThread(0); 224     return 0; 225 } 226   227 inetAddr.sin_family    = AF_INET; 228 inetAddr.sin_port    = htons(PUB_FILE_PORT); 229 inetAddr.sin_addr.s_addr = inet_addr(m_sip); 230   231   232 if (SOCKET_ERROR == connect(sFileRecv, (SOCKADDR *)&inetAddr, sizeof (SOCKADDR))) //连接服务器IP 233 { 234     AfxMessageBox( "连接对方主机错误 : threadRecvFile" ); 235     closesocket(sFileRecv); 236     AfxEndThread(0); 237     return 0; 238 } 239   240 //接收文件信息 241 FileInfo fiRecvFile; 242   243 if (SOCKET_ERROR == recv(sFileRecv, ( char *)&fiRecvFile, sizeof (FileInfo), 0)) 244 { 245     AfxMessageBox( "接收文件信息错误 : threadRecvFile" ); 246     closesocket(sFileRecv); 247     AfxEndThread(0); 248     return 0; 249 } 250   251 CString strFileInfo; 252 double nfileSize = 0.0; 253 if (fiRecvFile.nFileSizeLow / (1024 * 1024) != 0) 254 { 255     nfileSize = fiRecvFile.nFileSizeLow / (1024 * 1024); 256     strFileInfo.Format( "正在接收文件.../n 来自[%s], /n文件名[%s] 大小:[%.2f]MB" , 257          inet_ntoa(inetAddr.sin_addr), fiRecvFile.szFileTitle, nfileSize); 258 } 259 else 260 { 261     nfileSize = fiRecvFile.nFileSizeLow / (1024); 262     strFileInfo.Format( "正在接收文件.../n 来自[%s], /n文件名[%s] 大小:[%.2f]KB" , 263          inet_ntoa(inetAddr.sin_addr), fiRecvFile.szFileTitle, nfileSize); 264 } 265   266   267   268 CFileDialog fdlgSave( FALSE,NULL,fiRecvFile.szFileTitle, 269         OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, 270         _T( "所有 (*.*)|*.*|" )); 271   272 char buff[MAX_BUF_SIZE] = "" ; 273 CAcModuleResourceOverride thisResource; 274 if (fdlgSave.DoModal() != IDOK) 275 { 276      277     sprintf (buff, "%d" , MSG_REJECT); 278     send(sFileRecv, buff, sizeof (buff), 0); 279      closesocket(sFileRecv); //导致发送文件中端 280      AfxEndThread(0); 281 } 282   283 CString strFilePath; 284 strFilePath = fdlgSave.GetPathName(); 285   286 CFile fRecvedFile(strFilePath, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary); 287   288 DWORD dwTotalRead; 289 DWORD dwCurrentRead; 290   291 dwTotalRead   = 0; //接收总字节 292 dwCurrentRead = 0; //此次接收字节 293 BYTE *dataBuff = new BYTE [MAX_BUF_SIZE]; //分配堆内存缓冲 294   295 //开始接收 296 memset (buff, 0, sizeof (buff)); 297 sprintf (buff, "%d" , MSG_BEGIN); 298 send(sFileRecv, buff, sizeof (buff), 0); 299   300   301 while (dwTotalRead < fiRecvFile.nFileSizeLow) 302 { 303     dwCurrentRead = 0; 304     memset (dataBuff, 0, MAX_BUF_SIZE); 305   306     dwCurrentRead = recv(sFileRecv, ( char *)dataBuff, MAX_BUF_SIZE, 0); 307     if (0 == dwCurrentRead || SOCKET_ERROR == dwCurrentRead) 308     { 309      CString strFileRecvInfo; 310      strFileRecvInfo.Format( "接收:%s失败!" , fiRecvFile.szFileTitle); 311      312      break ; 313     } 314     fRecvedFile.Write(dataBuff, dwCurrentRead); 315     dwTotalRead += dwCurrentRead; 316 //   CString str; 317 //   str.Format("%d",dwTotalRead); 318 //   AfxMessageBox("已经接受"+str); 319   320     double iCompleted = 0.0; 321     iCompleted = (dwTotalRead * 1.0) / fiRecvFile.nFileSizeLow; 322     iCompleted *= 10.0; 323     CString strSavedInfo; 324     strSavedInfo.Format( "%d" , iCompleted); 325   326 } 327   328 delete dataBuff; //释放堆内存 329   330 CString strFileRecvInfo; 331 strFileRecvInfo.Format( "接收:%s完成!" , fiRecvFile.szFileTitle); 332 AfxMessageBox(strFileRecvInfo); 333   334 if (sFileRecv != INVALID_SOCKET) 335 { 336     closesocket(sFileRecv); 337 } 338   339 //关闭文件 340 fRecvedFile.Close(); 341 //清空文件信息 342 // memset(&pDlg->m_fiSendFile, 0, sizeof(pDlg->m_fiSendFile)); 343 // 344 AfxEndThread(0); 345 return 1; 346 }  347   348 //服务监听线程//建立服务器模型 349 UINT threadServer( LPVOID pvar) 350 { 351   352 SOCKADDR_IN inetAddr; 353 SOCKADDR_IN inetAccept; 354 SOCKET sAccept; 355 SOCKET MySock; 356      //服务器监听套接字MYSOCK; 357   358   359 MySock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); 360 if (INVALID_SOCKET == MySock) 361 { 362     AfxMessageBox( "套接字创建失败!" ); 363     return FALSE; 364 } 365   366 inetAddr.sin_family = AF_INET; 367 inetAddr.sin_port = htons(PUB_MSG_PORT);   //消息监听端口 368 //inetAddr.sin_port = 0; 369 inetAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); 370   371 //绑定 372 if (INVALID_SOCKET == bind(MySock, (SOCKADDR *)&inetAddr, sizeof (SOCKADDR))) 373 { 374     AfxMessageBox( "套接字绑定错误 : threadServer!" ); 375     closesocket(MySock); 376     return 0; 377 } 378   379 //监听 380 if (0 != listen(MySock, 5)) 381 { 382     AfxMessageBox( "套接字监听错误 : threadServer!" ); 383     return 0; 384 } 385   386 //    AfxMessageBox("消息服务启动成功"); 387   388 //accept 389 int ilen = sizeof (SOCKADDR_IN); 390   391 while (TRUE) 392 { //服务器会话套接字 393   394     sAccept = accept(MySock, (SOCKADDR *)&inetAccept, &ilen); 395   396     if (INVALID_SOCKET == sAccept) 397     { 398       AfxMessageBox( "接受套接字失败 : threadServer!" ); 399      return 0; 400     } 401      402     //启动消息处理线程处理新到达的消息 403      404     //分配堆内存,存放客户socket信息 405     SocketInfo *psInfo = new SocketInfo; 406     memset (psInfo, 0, sizeof (SocketInfo)); 407     psInfo->sNow   = sAccept; 408     psInfo->inetAddr = inetAccept; //客户机的地址 409      410      AfxBeginThread(threadRecvMsg, ( LPVOID )psInfo); 411 } //while 412   413 return 1; 414 } 415   416 //服务器处理 消息处理线程,新消息到达后启动,处理完毕关闭 417 UINT threadRecvMsg( LPVOID pvar) 418 { 419 SocketInfo *psockInfo = (SocketInfo *)pvar; 420 SocketInfo sockInfo = *psockInfo; 421 delete psockInfo; //释放堆内存 422 //每个线程里都有单独的内存,必须释放才能引用,实际上是子线程偷了父线程的内存 423      424   425 int iRecv = -1; 426 char buff[MAX_BUF_SIZE] = "" ; 427 char szMsg[256] = "" ; 428   429 //开始接收消息 430 iRecv = recv(sockInfo.sNow, buff, sizeof (buff), 0); // 431 if (SOCKET_ERROR == iRecv) 432 { 433     closesocket(sockInfo.sNow); 434     AfxMessageBox( "接收消息出错!: threadRecvMsg" ); 435     AfxEndThread(0); 436 } 437   438 //1001/暴风影音2007.exe/32MB/ 439 strcpy (szMsg, buff); 440 int itype = 0; 441 CString strTemp; 442 CString strInMsg; 443 strTemp += szMsg; 444 strInMsg += szMsg; 445 strTemp = strTemp.Left(4); 446 itype = atoi (strTemp); 447   448 //判断是否为文件到达消息 449 if (MSG_NEW_FILE == itype) 450 { 451   452     CString strMsgInfo; 453     CString strHost; 454     CString strFileName; 455     CString strSize; 456      457     int i, j; 458     i = 0; 459     j = 0; 460     i = strInMsg.Find( "/" ); 461     j = strInMsg.Find( "/" , i + 1); 462      463     //取得文件名称 464     strFileName = strInMsg.Mid(i + 1, j - i - 1); 465     strInMsg.TrimRight( "/" ); 466     //取得文件大小 467     strSize = strInMsg.Right(strInMsg.GetLength() - strInMsg.ReverseFind( '/' ) - 1); 468      469     strMsgInfo.Format( "[文件来源:%s]/n[文件名称:%s]/n[文件大小:%s]" , inet_ntoa(sockInfo.inetAddr.sin_addr), strFileName, strSize); 470     strMsgInfo += "/n同意接收吗?" ; 471     CAcModuleResourceOverride thisResource; 472     if (IDYES == MessageBox(NULL, strMsgInfo, "新消息" , MB_YESNO)) 473     { 474      char buffSend[MAX_BUF_SIZE] = "" ; 475      char sztemp[20] = "" ; 476      itoa(MSG_ACCEPT, sztemp, 10); 477      strcpy (buffSend, sztemp); 478       479      //发送同意接收消息给对方 480      if (SOCKET_ERROR == send(sockInfo.sNow, buffSend, sizeof (buffSend), 0)) 481      { 482         AfxMessageBox( "发送消息失败 : threadRecvMsg" ); 483       closesocket(sockInfo.sNow); 484       AfxEndThread(0); 485      } //if 486       487      488      char * senderip; 489      senderip=inet_ntoa(sockInfo.inetAddr.sin_addr); 490      //启动文件接收线程   491      AfxBeginThread(threadRecvFile, ( LPVOID )senderip); 492      493       494     } //if 495     else 496     { 497      char buffSend[MAX_BUF_SIZE] = "" ; 498      char sztemp[20] = "" ; 499      itoa(MSG_REJECT, sztemp, 10); 500      strcpy (buffSend, sztemp); 501       502      //发送拒绝接收消息给对方 503      if (SOCKET_ERROR == send(sockInfo.sNow, buffSend, sizeof (buffSend), 0)) 504      { 505       AfxMessageBox( "发送消息失败 : threadRecvMsg" ); 506       closesocket(sockInfo.sNow); 507       AfxEndThread(0); 508      } //if 509     } //else 510      511 } //if 512 else 513 { 514     AfxMessageBox( "无法识别的消息" ); 515 } //else 516   517   518 return 0; 519 }
    最新回复(0)