TCP发送文件(转)

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 }

你可能感兴趣的:(TCP发送文件(转))