网络编程基于TCP简易聊天室实验研究报告_第1页
网络编程基于TCP简易聊天室实验研究报告_第2页
网络编程基于TCP简易聊天室实验研究报告_第3页
网络编程基于TCP简易聊天室实验研究报告_第4页
网络编程基于TCP简易聊天室实验研究报告_第5页
已阅读5页,还剩42页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、个人收集整理仅供参考学习 网络编程课程设计 -基于TCP地简易聊天室 一、实验基本信息概要 1. 题目要求 熟悉异步网络编程地基本方法,掌握异步网络编程和网络协议设计地方法要求采用select 模型、WSAAsyncSelect模型、WSAEventSelect模型、重叠模型或完成端口等模型完成编程任 务.b5E2RGbCAP 2. 上机要求 要求采用select模型、WSAAsyncSelect模型、WSAEventSelect模型、重叠模型或完成端口等 模型完成下面地任务.p1EanqFDPw | 3. 题目内容 内容概要:实现一个聊天室,支持多人聊天.也可以增加私聊等功能. 4. 开发环

2、境 操作系统:Win dows 7 开发语言:C+ 集成开发环境:Microsoft Visual Studio 2010 14 / 41 二、系统简介 1.界面 本软件使用DOS控制台界面,界面风格较为朴素,没用使用复杂地颜色 进行了一定地控制和修正使得界面较为美观,易读.DXDiTa9E3d 服务器: S3 善理员 C:vjtndowssy$tem32cmd.exe - ChatServer.exe 6789 .但是对聊天时界面 c: XhatSeruer.exe 6789 System InFol成功绑定端诂7的 Systen服务器在67旳端开始监听 客户端: SBC:windovjss

3、ystem32cmd.exe - ChdtClientrexe 127.D.01 6?8 SAPASB KK U1D:128 说: hahah ASDC(12?-0.0A5 UID:132 说舌 lienliao DFGH127.0.0.1? U1D:136 说: 快点快点快点快点快点开 2) 私聊 使用命令【/m对方UID消息】即可发送私聊,私聊只有对方可以看到,如下图所示: 客户端1,密聊UID为132地用户. 【系统消息】昵称已修改为汀呗 Tom U1D:128 说: Jack UID:132 说: 你好,邂高牙见致他亠 加132你始莪和能单独聊聊吗? 发送后 【系统消息】昵称已修改为:

4、讪 rom UID:12S 说; Jack UID:132 说: 你妤,很高兴见到你 你“肖悄地对Jack UID:132 我们能单独聊聊吗? 客户端2,UID为132地用户收到私聊消息 ton UID:128 夫家寤、 JacP U1D:132 说* r你好,很高誹轴利您 Tom UID:128悄悄地对你说 你好,我们罷里独聊聊吗? I半: 3) 获取在线用户列表 使用命令【/list】即可获得在线用户列表,用户列表会议系统消息地方式返回,如下图所示 命令 【系统消恵J昵称已修改为:JAKRV 0.0.1 UIO:128 说: KK /list 半: 发送后 JARRV 【系统消息】昵称已修

5、理为: U1D:128 说; KK 【系统消息J在线人数共3人 KX 127.0.0.1 UID:12S Jack 127-0.0.1U1D:132 JARRY 127,0.0,1UID:136 4) 更改昵称 使用命令【/name你地新昵称】即可立即更改昵称,成功修改后服务器会以系统消息地方 式返回成功修改地提示.RTCrpUDGiT 命令 SB 官埋员 C :w i n dowssy st e m 3 2 cm d BC UID:136 说; 看看我叫什么名字? n atne DFGH 命令发送后 J L SB 管理员:C: /A n d owssyst e m 3 2 .cm d. e

6、e - 5) 帮助信息 使用命令【/help】即可查看服务器地欢迎信息,里面包含了该聊天室地使用帮助,如下图 所示. 命令 S3 营理员:CAwindowssystemS2cmd.exe - CI fiDC UID:132 I SADASD /he lp 命令发送后 SB 营理员:C:windov7$system32cmnd.exe - ChjtClient.exe 127 0.0.1 6789 SDC UIDH32 * 欢迎使 SADASB .T _ U H U 加共聊天消息 信息 釁户 命令指南土 USAGE USAGE USAGE USAGE USAGE /exit /list /nam

7、e你的昵称 如对方DID消息 /help 岀叢常 H8 12 3 4 5 3. 系统设计 开发本软件时,我使用了面向对象地思想,把服务器和客户端封装成对应地类,类设计将会 在下一节做详细介绍. 通行方面我在服务器接受客户端消息,和客户端接受服务器消息时使用了select模型,发送 信息我使用地是普通地SOCket原语.5PCzVD7HxA 基本原理为服务器与客户端建立TCP连接,然后服务器负责路由消息到各个客户端 4. 优点与缺点 本软件对流程复杂地SELECT莫型进行了细致地拆分与抽象,做到了逻辑流程清晰,每个函 E void Chat Server: : St art () InitLis

8、tenSocket (): Bind(): Listen(); InitFDSocket (); while Ct rue) DoSelect (): 数简洁易懂,层次分明.例如服务器启动函数:jLBHrnAlLg try charServer. Start (). J catch (SockExceptionife e) coxit e* GetErrorlnfc () endl: cout System ErrorjError Cede; GetErrorCode() 0) for (int i = 0: i count : i+) DoFDRead(m_f dRead. fd_array

9、i): 它也只完成一个简单地流程,调用select,然后循环处理有读事件地socket. void Chat S erver: DoFDRe ad (SOCKET sRe ad) if (sKead = Jh_sList en) RecvNewConnect (); else m_sNowlient = sRead; RecvNevMessage(): 接下来地DoFDRead ()函数完成地事情也非常直接,如果有事件地socket是监听socket地 话,那么就是接收到了一个新地连接,否则是接收到了新地小.LDAYtRyKfE 从上面这个简单地例子中可以看到,本软件最大地优点就是精心设计地类

10、和函数避免了使 用select模型常见地反复嵌套地循环和判断,每个函数清晰明了.Zzz6ZB2Ltk 本系统还存在以下不足,首先是没有对界面做更深入地优化,只是做了最基本地调整,让输 入输出更加雅观,其次是底层原语地封装并没有考虑到泛用性.dvzfvkwMI1 三、系统详细设计 这部分地文档在编码之前已经基本完成, 由于时间较为仓促, 部分内容可能和实际有所出入 1. ChatServer类 该类负责完成服务器所有操作 1)类图 ChatServer Class dP -字段 ”* m_dienls 少 m_fdRead m_fdSocket 护 nrinPort m_slJsten m sN

11、owClient MFmi ChatServer ass 出字段 a方 v ChatServer .沪 Accept 士” AddClientToInfoMap 多 Bind 屮 BuildMessage 屮 BuildSystemMg ChatServer 旷 CloseConnect 八 DispatchMessage 屮 DoCmdGetUsers 屮 DoCrndName Do匚mdPrivateMsg 卜 DoCommand 尅 DoFDRead 屮 DoMessage DoSeledt End 屮 InitFDSocket 1 卜 InitListenSocket .我 IntTo

12、String 点 IPAddrToString IsCommand 2) 成员变量 Map m_clients 聊天者地 SOCKET与昵称地映射 fd_set m_fdSocket可用套接字集合 fd_set m_fdRead有事件发生地套接字集合 SOCKET m_sListen监听 Socket SOCKET m_sNowClie nt当前处理地客户套接字 int m_nPort 监听端口 3) 方法设计 void Bi nd() void Liste n() void Select() int Recv() SOCKET Accept() 封装底层原语,并加入异常机制,使得外部调用简约

13、明了 构造函数 传入监听端口,初始化m_nPort Start() 1) 初始化监听套接字:void In itListe nSocket() 2) 绑定套接字至本地机器:void Bin d() 3) 进入监听模式(设置为非阻塞):void Listen() 4) 初始化可用套接字集合void In itFDSocket() 5) 死循环,调用 select方法 DoSelect() 6) 结束 DoSelect() 1) 令 m_fdRead = m_fdSocket 2) 调用 Select() 3) 循环处理 Select 地结果 DoFdRead(Socket sRead) 4) 结

14、束 DoFdRead(i nt iReadl ndex) 1) 判断是否为 m_sListe n 2) 是 m_sListen RecvNewConnect() 3) 否则 令 m_sNowClient = m_fdReadiReadlndex,调用 RecvNewMessage()rqyni4ZNXi RecvNewCo nn ect() 1) 判断是否达到套接字上线 2) 调用Accept(),接收连接sClient 3) 添加 sCilent 至 m_fdSocket 4) 添加套接字至 m_clie nts AddClie ntTol nfoMap(stri ng name) AddC

15、lie ntTo In foMap(stri ng n ame) 1) 以SOKCET为键,name为值加入MAP RecvNewMessage() 1) 调用Recv函数 2) 是否为命令 IsComma nd(stri ng str) 3) 是,贝U DoCommand(string cmd) 4) 否,贝U DoMessage(string msg) 5) 结束 IsComma nd(stri ng str) 1) 判断是否以”/”开头 DoComma nd(stri ng cmd) 1) 判断指令,并解析命令与参数(argc, argv) 2) 调用指令处理函数 3) 假设只有SetN

16、ame命令,那么则将对应地套接字地名称设置 DoMessage(stri ng msg) 1) 拼接消息与名字BuildMsg(stri ng msg) 2) 在服务器上输出 3) 消息路由 DispatchMessage(stri ng msg) BuildMsg(stri ng msg) 1) 从m_clients中取出用户昵称 2) 拼接字符串,形成格式如下 超人君(127.0.0.1) 23:49:48 说: 大家好! 即为: 昵称(IP地址)时间说: 消息正文 3)返回 DispatchMessage(stri ng msg) 1)构造迭代器 2) 遍历m_clients,若不是自身

17、,则派送消息Send() 2. ChatClient 类 该类负责处理客户端地所有操作 1)类图 Chatclient 字段 .、* m name msClient m_serverAddr *、* m sServer ChatClient +字段 -审去 Y hat Client Chat Client Connect DoComiTiancl DdV essage End Get ClientSock Get Line nitClientSocket IritName IPAddrToString 【K ommand Recv ResoveCornm. Select Send SendMs

18、g Start Welcome SOCKET m_sClie nt SOCKET m_sServer stri ng m_n ame 客户端自身地 socket 服务器socket 昵称 sockaddr in m ServerAddr; 服务器地址 3) 方法设计 构造函数 根据端口号和服务器IP初始化m_server Conn ect() void Select() int Recv() void Se nd() int Select() 封装底层原语,加入异常处理,使得外部调用节约优雅 void Start() 1) 初始化套接字Ini tClie ntSocket() 2) 连接服务器

19、Connect()设置为非阻塞模式 3) 获取名字并发送至服务器Ini tName() 4) 创建新线程并显示替他用户发言线程函数RecvMsgThread() 5) 循环 SendMsg() 6) 关闭客户端CloseClie nt() Ini tName() 1) 提示输入昵称 2) 获取昵称 3) 合法性判断 判断重复 4) 添加命令格式 5) 发送至服务器 Sen dMsg() 1)读取一行消息 2)判断是否为命令 3)命令:处理命令 4)消息:处理消息 IsComma nd(stri ng str) DoComma nd(stri ng cmd) DoMessage(stri ng

20、msg) DoMessage(stri ng msg) 1) 发送消息 Se nd() 2) 本地回显 RecvMsgThread() 1) 初始化 fdSocket,将 m_sClient 加入 2) 创建 fdRead 3) 死循环,将m_sClient拷贝至fdRead 4) 调用 Select 5) 循环,并输出收到地消息Recv() 3. SocketException类 该类负责记录SOKCET错误地代码以及错误信息 1)类图 个人收集整理仅供参考学习 ScckExccption Class 匕学段 -# m_r ErrorCode # m_strrrQrnfo 二為去 V Get

21、ErrorCode V GetErrorlrfo v SetErrorCode v SetErrorlnfc SockExceptior 4. 命令协议 命令格式为/命令参数1参数2 1. 退出:/exit 2. 获取在线用户列表:/getuser 3. 私聊:/m UID信息 4. 清屏:/clear 5. 帮助:/help 处理方式 IsCommand(string str)负责解析是否为命令 判断首字母是否为斜杠”/” str.at(O) = / ResoveCommand(string cmd, int 说: Jack UID:136悄悄地对你说; 你好! : 你悄悄地对ABC UID

22、:132说: a asdasdasd 1234 asdasd 1234 asdasd 1234(127.0.0-l asdads 1234C127.0-0-l asdasd 1234 asd 1234C127.0.0-1) asdasd UID:128 UID:128 UID:128 UID:128 UID:128 UID:128 说: 说= 说; 说: 半: flE 10.错误地私聊 私聊自己会得到一个错误提示 【系统消息】昵称已修改为二血 JACK UID:128 说: 夭象妊 g 128快快快快看 【系统消息J昵称已修改为二朋 JACKC127.0.0-1 UID:128 说; 【蘇需息

23、】您不能和自己私聊 私聊不存在地用户也会得到一个错误提示 AAA 127.0-0.1UID:128 as das das d 127. Ei.0.1 U1D: 132 Jack 127.0.0.1UID:136 n 1在吗? 半: 127.0,0.1UID:128 u A 息息AA 歆自 充充 系系 a Ini tSock in itSock; int main (i nt argc, char* argv) if (argc 2) cout Usage: argv0 Port endl; return 1; ChatServer charServer(atoi(argv1); try cha

24、rServer.Start(); catch (SockExcepti on cout System ErrorError Code: e.GetErrorCode() en dl; .这次试验也使我在编 kavU42VRUs ChatServer.h服务器类头文件 #ifndef CHAT_SERVER_H #defi ne CHAT_SERVER_H #i nclude #in elude #in elude #i nclude Clie ntln fo.h using n amespace std; class ChatServer public: void Start(); void

25、En d(); ChatServer(i nt nPort); ChatServer(void); private: void In itFDSocket(); void DoSelect(); void DoFDRead(SOCKET sRead); void RecvNewC onn ect(); stri ng IPAddrToStri ng(sockaddr_ in sin); void AddClie ntTol nfoMap(Clie ntl nfo in fo); void RecvNewMessage(); bool IsComma nd(stri ng str); void

26、DoComma nd(stri ng cmd); void ResoveCommand(string cmd, int y6v3ALoS89 void DoCmdName(i nt argc, stri ng argv); void DoCmdGetUsers(i nt argc, stri ng argv); void DoMessage(stri ng msg); void DoCmdPrivateMsg(i nt argc, stri ng argv); string BuildMessage(string str, bool bIsPublic); stri ng BuildSyste

27、mMsg(stri ng str); void DispatchMessage(stri ng msg); void CloseC onn ect(); string IntToString(int nNum); /=简单封装底层原语= void In itListe nSocket(); void Bin d(); void Liste n(); int Select(); int Recv(char msgBuff); void Sen d(stri ng msg, SOCKET clie nt); SOCKET Accept(sockaddr_i n /= private: map m_

28、clie nts; fd_set m_fdSocket; fd_set m_fdRead; SOCKET m_sListe n; SOCKET m_sNowClie nt; int m_n Port; ; #en dif CHAT_SERVER_H ChatServer.cpp 服务器类 #i nclude #in clude #in clude ChatServer.h #i nclude SockExceptio n.h #pragma comme nt(lib, ws2_32.lib) using n amespace std; #defi ne MAX_BUFF_SIZE 500 ty

29、pedef map:iterator map_it; ChatServer:ChatServer(i nt nPort) this-m _n Port = n Port; void ChatServer:Start() In itListe nSocket(); Bin d(); Liste n(); In itFDSocket(); while (true) DoSelect(); void ChatServer:DoSelect() m_fdRead = m_fdSocket; int n Ret = Select(); if (n Ret 0) for (i nt i = 0; i =

30、FD_SETSIZE) endl; cout System Info接受连接达到上限,拒绝连接 return; sockaddr_ in clie ntAddr; m_sNowClie nt = Accept(clie ntAddr); Clie ntl nfo clie ntln fo(clie ntAddr); cout System Info接受来自 clientlnfo.Getlp() 地连接 endl;M2ub6vSTnP FD_SET(m_sNowClie nt, AddClie ntToI nfoMap(clie ntln fo); stri ng ChatServer:IPAd

31、drToStri ng(sockaddr_i n sin) stri ng str = inet_n toa(s in.sin _addr); str.appe nd(:); char szFormat20; str.append(ltoa( ntohs(sin.sin_port),szFormat,10); OYujCfmUCw return str; void ChatServer:AddClientTolnfoMap(Clientlnfo info) eUts8ZQVRd m_clie ntsm_sNowClie nt = info; void ChatServer:RecvNewMes

32、sage() char msgBuffMAX_BUFF_SIZE; int n Ret = Recv(msgBuff); stri ng msg(msgBuff); if (n Ret = 0) retur n; if (IsComma nd(msg) DoComma nd(msg); else DoMessage(msg); void ChatServer:DoComma nd(stri ng cmd) int argc; stri ng argv100; ResoveComma nd(cmd, argc, argv); if (argv0 = n ame) DoCmdName(argc,

33、argv); else if (argv0 = list) DoCmdGetUsers(argc, argv); else if(argvO = m) DoCmdPrivateMsg(argc, argv); else 命令查看命令帮助, GMsIasNXkA Send(”【系统消息】命令不存在,请使用/help m_sNowClient); sQsAEJkW5T void ChatServer:ResoveComma nd(stri ng cmd, i nt for(i nt i = 1; i sec on d.GetName()+ begi n-seco nd.Getlp(); 7EqZc

34、WLZNX msg.append( UID: + IntToString(int)begin-first); izq7IGfO2E msg.appe nd(nr); Sen d(msg, m_sNowClie nt); void ChatServer:DoCmdName(int argc, string argv) zvpgeqj1hk if (argc != 2) Send(”【系统消息】 命令格式错误 USAGE: /name 你地昵称, m_sNowClient); NrpoJac3v1 return; stri ng n ame = argv1; m_clie ntsm_sNowCli

35、e nt.SetName( name); Send(”【系统消息】昵称已修改为:+ name, m_sNowClient); void ChatServer:DoMessage(stri ng str) string msg = BuildMessage(str, true); cout msg en dl; DispatchMessage(msg); /* string ChatServer:BuildMssage(string str) ClientInfo info = m_clientsm_sNowClient; stri ng n ame = in fo.GetName(); str

36、i ng ip = in fo.GetIp(); stri ng msg = n ame; if (n ame != ip) msg.appe nd(”(” + ip + ); char buff10; string id(itoa(int)m_sNowClient, buff, 10); msg.append( UID: + id); msg.append(” 说:); msg.appe nd(nr); msg.appe nd(str); return msg; */ stri ng ChatServer:BuildSystemMsg(stri ng str) string msg(【系统消

37、息】); msg.appe nd(str); return msg; string ChatServer:BuildMessage(stri ng str, bool bIsPublic) 1nowfTG4KI ClientInfo info = m_clientsm_sNowClient; stri ng n ame = in fo.GetName(); stri ng ip = in fo.Getlp(); string uid = IntToString(int)m_sNowClient); stri ng msg( name); if (ip != n ame msg.appe nd(

38、” ); msg.appe nd(UID: + uid); ”);fjnFLDa5Zo msg.appe nd(” ); bIsPublic ? msg.append(说:):msg.append(悄悄地对你说: msg.appe nd(nr); msg.appe nd(”); msg.appe nd(str); return msg; void ChatServer:DoCmdPrivateMsg(int argc, string argv) tfnNhnE6e5 if (argc first = m_sNowClie nt) Send(”【系统消息】您不能和自己私聊, m_sNowClie

39、nt); return; stri ng n ame = it-sec on d.GetName(); string uid = IntToString(s); stri ng toDest = BuildMessage(, false); string toSrc = string(你悄悄地对 + name + UID: + uid + 说:nr”); V7i4jRB8Hs string other; for (int i = 2; i first); bool ChatServer:IsComma nd(stri ng str) if (str.at(0) = /) return true

40、; else return false; void ChatServer:CloseC onn ect() cout System Info来自 ” m_clientsm_sNowClient.Getlp() 地连接已断开 en dl;83lcPA59W9 closesocket(m_sNowClie nt); FD_CLR(m_sNowClie nt, void ChatServer:I nitFDSocket() FD_ZERO ( FD_SET(m_sListe n, void ChatServer:I nitListe nSocket() m_sListe n = socket(AF_

41、INET, SOCK_STREAM, IPPROTO_TCP)klkzaaP if (m_sListen = INVALID_SOCKET) throw SockException(System Error创建套接字失败:); void ChatServer:Bi nd() sockaddr_ in sin; si n.sin_family = AF_INET; si n.sin_addr.S_ un .S_addr = INADDR_ANY; sin.sin _port = hton s(m_ nPort); if (bin d(m_sListe n, (sockaddr*) void Ch

42、atServer:Liste n() if (liste n(m_sListe n, 10) = SOCKET_ERROR) throw SockException(System Error服务器监听端口失败 ”); else cout System Info服务器在 m_nPort 端口开始监听 endl; ORjBnOwcEd u_long value = 1; if (ioctlsocket(m_sListen, FIONBIO, 2MiJTy0dTT int ChatServer:Select() int n Ret = select(0, if (n Ret = SOCKET_ERR

43、OR) throw SockException(System Error调用 SELECT原语失败); else return n Ret; SOCKET ChatServer:Accept(sockaddr_i n SOCKET sNew = accept(m_sListe n, (sockaddr*) gIiSpiue7A if (sNew = INVALID_SOCKET) throw SockException(System Error调用 ACCEPT原语接受连接失败 ”);uEh0U1Yfmh return sNew; int ChatServer:Recv(char msgBuf

44、f) int n Ret = recv(m_sNowClie nt, msgBuff, MAX_BUFF_SIZE, 0)Ag9qLsgBX if (n Ret = SOCKET_ERROR) CloseC onn ect(); return 0; else msgBuff nRet = 0: return n Ret; void ChatServer:Se nd(stri ng msg, SOCKET clie nt) if (se nd(clie nt, msg.c_str(), msg.size(), 0) = SOCKET_ERROR)wghWvVhPE string errorIp

45、= m_clientsclient.Getlp(); throw SockException(System Error发送信息+ msg + 至+ errorIp + 失败 );asfpsfpi4k stri ng ChatServer:I ntToStri ng(i nt nNum) char buff1O; string str(itoa(nNum, buff, 10); return str; ChatServer:ChatServer(void) Clientinfoh客户信息类 #in clude using n amespace std; class Clie ntlnfo pub

46、lic: Clie ntln fo() Clientlnfo(string ip, int port, string name) this-ip = ip; this-port = port; this-n ame = n ame; Clie ntl nfo(sockaddr_ in sin) ip = inet_n toa(s in.sin _addr); /port = n tohs(s in.sin _port); n ame = ip; n ame.appe nd(:); /char szFormat20; ooeyYZTjj1 n ame.appe nd(ltoa( n tohs(s

47、 in.sin _port),szFormat,10); stri ng GetIp() return ip; stri ng GetName() return n ame; int GetPort() return port; void SetName(stri ng n ame) this-n ame = n ame; private: stri ng n ame; stri ng ip; int port; ; Charclientd.cpp 客户端 main 函数 #i nclude SockExcepti on.h #in elude In itSock.h #in clude #i

48、n clude ChatClie nt.h using n amespace std; Ini tSock in itSock; int main (i nt argc, char* argv) try if (argc 3) cout Usage: argv0 Ip Port endl; BkeGuinkxi return 1; ChatClie nt clie nt(argv1,atoi(argv2); clie nt.Start(); catch (SockExcepti on cout System ErrorError Code: e.GetErrorCode() endl; Pgd

49、OOsRlMo ChatClienth客户端头文件 #ifndef CHAT_CLIENT_H #defi ne CHAT_CLIENT_H #in clude #i nclude using n amespace std; class ChatClie nt public: ChatClie nt(stri ng addr, i nt nPort); ChatClie nt(void); void Start(); void En d(); SOCKET GetClie ntSock(); private: void Conn ect(); int Recv(); void Sen d(st

50、ri ng msg); int Select(); void Ini tClie ntSocket(); stri ng IPAddrToStri ng(sockaddr_ in sin); void Welcome(); void Sen dMsg(); void In itName(); bool IsComma nd(stri ng str); void DoMessage(stri ng msg); void DoComma nd(stri ng cmd); 3cdXwckm15 void ResoveComma nd(stri ng cmd, int stri ng GetL in

51、e(); private: stri ng m_n ame; SOCKET m_sClie nt; SOCKET m_sServer; sockaddr_ in m_serverAddr; ; #e ndif CHAT_CLIENT_H ChatClient .cpp 客户端类 #i nclude #in clude #in clude #in clude #in clude ChatClie nt.h #i nclude SockExceptio n.h #pragma comme nt(lib, ws2_32.lib) #defi ne MAX_BUFF_SIZE 500 using n

52、amespace std; void RecvMsgThread(void * param); ChatClient:ChatClient(string addr, int nPort) m_serverAddr.sin_addr.S_un.S_addr = inet_addr(addr.c_str(); h8c52WOngM m_serverAddr.sin_port = htons(n Port); m_serverAddr.sin_family = AF_INET; ChatClie nt:ChatClie nt(void) void ChatClie nt:Start() Ini tC

53、lie ntSocket(); Conn ect(); Welcome(); Sleep(1000); In itName(); _begi nthread(RecvMsgThread,NULL,(void*)this); while (true) Sen dMsg(); void ChatClie nt:Welcome() cout = endl; v4bdyGious cout *欢迎使用简易聊天室* endl; J0bm4qMpJ9 cout 操作指南:1)在控制台中直接输入后,按回车即可发送公共聊天消息 endl; cout 2)以斜杠(/)开头地消息将会当做命令处理” en dl;X

54、VauA9grYP cout endl; bR9C6TJscw cout 命令指南:1)退出USAGE: /exit endl; pN9LBDdtrd cout 2)获取在线用户USAGE: /list endl; DJ8T7nHuGT cout 3)更改昵称 USAGE: /name你地昵称 endl; QF81D7bvUA cout 4)私聊 USAGE: /m对方UID消息 endl; 4B7a9QFw9h cout 5)帮助信息 USAGE: /help endl; ix6iFA8xoX cout = endl; wt6qbkCyDE void ChatClie nt:l ni tNa

55、me() stri ng n ame; cout 请输入昵称:; n ame = GetL in e(); Sen d(/name + n ame); void ChatClie nt:Se ndMsg() stri ng msg; msg = GetL in e(); if (msg =) return; if (IsComma nd(msg) DoComma nd(msg); else DoMessage(msg); string ChatClient:GetLine() stri ng in put; getl in e(ci n, in put); HANDLE hOut = GetS

56、tdHa ndle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO bI nfo; GetCo nsoleScree nBuferl nfo(hOut, COORD pos; pos.X = bln fo.dwCursorPositi on.X; pos.Y = bln fo.dwCursorPositi on.Y - 1; FillConsoleOutputCharacter(hOut, , input.size(), pos, NULL); Kp5zH46zRk SetC on soleCursorPositi on( hOut, pos);

57、return in put; void ChatClie nt:DoComma nd(stri ng cmd) int argc; stri ng argv100; ResoveComma nd(cmd, argc, argv); if (argv0 = exit) system(exit); else if (argv0 = help) Welcome(); else DoMessage(cmd); void ChatClie nt:DoMessage(stri ng msg) /TODO Sen d(msg); void ChatClient:ResoveCommand(string cm

58、d, int for(i nt i = 1; i cmd.size(); i+) char c = cmd.at(i); if (c !=) argvco unt += c; else count +; argc = +co unt; bool ChatClie nt:lsComma nd(stri ng str) if (str.at(O) = /) return true; else return false; void ChatClie nt:l ni tClie ntSocket() m_sClie nt = socket(AF_INET, SOCK_STREAM, IPPROTO_T

59、CPpJx4Bli if (m_sClie nt = INVALID_SOCKET) throw SockException(System Error创建套接字失败); void ChatClie nt:Co nn ect() if(conn ect(m_sClie nt,(sockaddr* )E836L11DO5 else cout System Info连接服务器 ” + IPAddrToString(m_serverAddr) + 成功” GetClie ntSock(), fd_set fdRead; char msgBuffMAX_BUFF_SIZE; while (true) f

60、dRead = fdSocket; if (select(0, i 0) msgBuff nRet = 0; cout msgBuff en dl; SOCKET ChatClie nt:GetClie ntSock() return m_sClie nt; InitSock.cpp 初始化 WINSOCK类 #ifndef INITSOCK_H #defi ne INITSOCK_H #i nclude #pragma comme nt(lib, WS2_32) class In itSock public: In itSock(BYTE minorVer = 2, BYTE majorVe

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论