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 }
转载请注明原文地址: https://ibbs.8miu.com/read-2266311.html