|
基于TCP的局域网多用户通信、文件传送程序详解
湖南涟源农机学校:刘文博
源代码下载 逆风者
看了袁渊先生在VC知识库《在线杂志》第14期发表的文章《基于TCP/IP的局域网多用户通信》,感觉受益颇多,但也觉得里面有一些不太完善的地方,具体来说主要有:
- 两个服务器单独运行,且主线程均阻塞,用户界面死锁,不便于控制;
- 聊天服务器线程和互斥量的使用可能导致死锁;
- 不能实现文件传送(文件传送可不能由服务器转发,否则非把它累趴下不可^-^);
- 不能由用户进行网络设置,所以在不同的网络使用必须修改源程序等等;
我在此基础上重新设计编写了一个系统,具体如下:
一、构架设计
整个系统分为三个相关的程序模块,即注册登陆服务器(wbQQRegSer)、聊天通信服务器(wbQQChat)以及用户程序(wbQQClient)。其中,注册登陆服务器负责用户的注册、登陆以及数据库管理;通信服务器负责完成数据转发以及共享数据结构的管理;用户端则完成注册、登陆、通信和文件传送功能。在进行文件传送时,任一客户程序均可以既作为文件传送服务器发送文件,也可以作为客户端接收文件,实现半双工的文件传送。整个系统构成如图一:

图一 系统构架图
二、注册登录服务器设计
注册登录服务器采用面向连接的并发式方式,服务器设计成为一个对话框程序。调用WSAStartup初始化动态库,socket函数创建套接字,bind函数绑定本地IP地址和端口,listen函数使套接字进入侦听,然后由于调用accept()函数将产生阻塞,所以不宜在主线程中调用该函数,因而在初始化网络后当用户按下“运行注册登录服务器”按钮后,利用侦听套接字启动注册登录线程RegLoad(void *s)进入无限循环,在线程中调用accept函数,用来接受来自客户端的连接请求,每当一个连接请求到来时,accept()函数将产生一个新的套接字,利用这个套接字产生一个新的线程talkToClient(void *cs)与客户端进行通信并读写数据库,通信完毕后关闭该套接字和线程,原来的侦听套接字继续处于侦听状态。
两个服务器程序可以在同一台物理机器上运行,也可以在不同的机子上运行,为方便服务器的控制,在注册登录服务器调用函数
CreateProcess( NULL,
".\\..\\wbQQChat\\wbQQChat.exe", // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent''''s environment block.
NULL, // Use parent''''s starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi )
创建聊天通信服务器进程,想关闭时则调用TerminateProcess(m_hProcChat, 2)函数关闭此进程。
三、聊天通信服务器设计
聊天通信服务器设计为无界面的进程(创建时先建一个基于对话框的应用程序,然后把对话框类删除,把APP类里面与对话框有关的语句全删除即可创建无界面进程),采用共享数据结构,为每个客户端创建两个线程,实现接收和转发的功能。第一个线程用于发送,hHandleSend = AfxBeginThread(SendData,(LPVOID)clientSocket,0,0,CREATE_SUSPENDED,NULL);
第二个线程用于接收:
hHandleRecv = AfxBeginThread(RecvData, (LPVOID)clientSocket);
四、客户端设计
客户端设计成为对话框的用户界面,主要分成四个模块,分别是注册模块、登录模块、聊天模块和文件传送模块。
本文章更多内容:1 - 2 - 3 - 下一页>> |