对应的Linux服务器为:http://blog.csdn.net/microtong/archive/2009/12/12/4989902.aspx

头文件ClientDlg.h

[cpp] view plaincopy
  1. // ClientDlg.h : 头文件
  2. //
  3. #pragma once
  4. #include "afxcmn.h"
  5. #include "afxwin.h"
  6. #define WM_NETWORK WM_USER+100
  7. // CClientDlg 对话框
  8. class CClientDlg : public CDialog
  9. {
  10. // 构造
  11. public:
  12. CClientDlg(CWnd* pParent = NULL);   // 标准构造函数
  13. // 对话框数据
  14. enum { IDD = IDD_CLIENT_DIALOG };
  15. protected:
  16. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
  17. // 实现
  18. protected:
  19. HICON m_hIcon;
  20. // 生成的消息映射函数
  21. virtual BOOL OnInitDialog();
  22. afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
  23. afx_msg void OnPaint();
  24. afx_msg HCURSOR OnQueryDragIcon();
  25. DECLARE_MESSAGE_MAP()
  26. public:
  27. CIPAddressCtrl m_ip;
  28. int m_port;
  29. CEdit m_allmsg;
  30. CString m_nickname;
  31. CString m_message;
  32. afx_msg void OnBnClickedConnect();
  33. // 服务器套接字
  34. SOCKET sock;
  35. struct sockaddr_in serverAddr;
  36. CString msg;
  37. LRESULT OnNetwork(WPARAM wParam, LPARAM lParam);
  38. void OnConnect(SOCKET s);
  39. void OnRead(SOCKET s);
  40. void OnCloseSocket(SOCKET s);
  41. afx_msg void OnBnClickedSend();
  42. afx_msg void OnBnClickedDisconnect();
  43. afx_msg void OnClose();
  44. afx_msg void OnBnClickedQuit();
  45. afx_msg void OnBnClickedChangeName();
  46. };

对话框源文件 ClientDlg.cpp

[cpp] view plaincopy
  1. // ClientDlg.cpp : 实现文件
  2. //
  3. #include "stdafx.h"
  4. #include "Client.h"
  5. #include "ClientDlg.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #endif
  9. // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
  10. class CAboutDlg : public CDialog
  11. {
  12. public:
  13. CAboutDlg();
  14. // 对话框数据
  15. enum { IDD = IDD_ABOUTBOX };
  16. protected:
  17. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
  18. // 实现
  19. protected:
  20. DECLARE_MESSAGE_MAP()
  21. };
  22. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  23. {
  24. }
  25. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  26. {
  27. CDialog::DoDataExchange(pDX);
  28. }
  29. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  30. END_MESSAGE_MAP()
  31. // CClientDlg 对话框
  32. CClientDlg::CClientDlg(CWnd* pParent /*=NULL*/)
  33. : CDialog(CClientDlg::IDD, pParent)
  34. , m_port(8000)
  35. , m_nickname(_T("microtong"))
  36. , m_message(_T("hello"))
  37. {
  38. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  39. }
  40. void CClientDlg::DoDataExchange(CDataExchange* pDX)
  41. {
  42. CDialog::DoDataExchange(pDX);
  43. DDX_Control(pDX, IDC_IP, m_ip);
  44. DDX_Text(pDX, IDC_PORT, m_port);
  45. DDX_Control(pDX, IDC_ALLMESSAGE, m_allmsg);
  46. DDX_Text(pDX, IDC_NICKNAME, m_nickname);
  47. DDV_MaxChars(pDX, m_nickname, 30);
  48. DDX_Text(pDX, IDC_MESSAGE, m_message);
  49. DDV_MaxChars(pDX, m_message, 1024);
  50. }
  51. BEGIN_MESSAGE_MAP(CClientDlg, CDialog)
  52. ON_WM_SYSCOMMAND()
  53. ON_WM_PAINT()
  54. ON_WM_QUERYDRAGICON()
  55. //}}AFX_MSG_MAP
  56. ON_BN_CLICKED(IDC_CONNECT, &CClientDlg::OnBnClickedConnect)
  57. ON_BN_CLICKED(IDC_SEND, &CClientDlg::OnBnClickedSend)
  58. ON_BN_CLICKED(IDC_DISCONNECT, &CClientDlg::OnBnClickedDisconnect)
  59. ON_WM_CLOSE()
  60. ON_BN_CLICKED(IDC_QUIT, &CClientDlg::OnBnClickedQuit)
  61. ON_BN_CLICKED(IDC_CHANGENAME, &CClientDlg::OnBnClickedChangeName)
  62. ON_MESSAGE(WM_NETWORK,&CClientDlg::OnNetwork)
  63. END_MESSAGE_MAP()
  64. // CClientDlg 消息处理程序
  65. BOOL CClientDlg::OnInitDialog()
  66. {
  67. CDialog::OnInitDialog();
  68. // 将“关于...”菜单项添加到系统菜单中。
  69. // IDM_ABOUTBOX 必须在系统命令范围内。
  70. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  71. ASSERT(IDM_ABOUTBOX < 0xF000);
  72. CMenu* pSysMenu = GetSystemMenu(FALSE);
  73. if (pSysMenu != NULL)
  74. {
  75. CString strAboutMenu;
  76. strAboutMenu.LoadString(IDS_ABOUTBOX);
  77. if (!strAboutMenu.IsEmpty())
  78. {
  79. pSysMenu->AppendMenu(MF_SEPARATOR);
  80. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  81. }
  82. }
  83. // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
  84. //  执行此操作
  85. SetIcon(m_hIcon, TRUE);         // 设置大图标
  86. SetIcon(m_hIcon, FALSE);        // 设置小图标
  87. // TODO: 在此添加额外的初始化代码
  88. //为测试方便IP地址初始化为本机IP地址
  89. m_ip.SetAddress(127,0,0,1);
  90. return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
  91. }
  92. void CClientDlg::OnSysCommand(UINT nID, LPARAM lParam)
  93. {
  94. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  95. {
  96. CAboutDlg dlgAbout;
  97. dlgAbout.DoModal();
  98. }
  99. else
  100. {
  101. CDialog::OnSysCommand(nID, lParam);
  102. }
  103. }
  104. // 如果向对话框添加最小化按钮,则需要下面的代码
  105. //  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
  106. //  这将由框架自动完成。
  107. void CClientDlg::OnPaint()
  108. {
  109. if (IsIconic())
  110. {
  111. CPaintDC dc(this); // 用于绘制的设备上下文
  112. SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
  113. // 使图标在工作矩形中居中
  114. int cxIcon = GetSystemMetrics(SM_CXICON);
  115. int cyIcon = GetSystemMetrics(SM_CYICON);
  116. CRect rect;
  117. GetClientRect(&rect);
  118. int x = (rect.Width() - cxIcon + 1) / 2;
  119. int y = (rect.Height() - cyIcon + 1) / 2;
  120. // 绘制图标
  121. dc.DrawIcon(x, y, m_hIcon);
  122. }
  123. else
  124. {
  125. CDialog::OnPaint();
  126. }
  127. }
  128. //当用户拖动最小化窗口时系统调用此函数取得光标显示。
  129. //
  130. HCURSOR CClientDlg::OnQueryDragIcon()
  131. {
  132. return static_cast<HCURSOR>(m_hIcon);
  133. }
  134. void CClientDlg::OnBnClickedConnect()
  135. {
  136. UpdateData(TRUE);
  137. DWORD ip;
  138. m_ip.GetAddress(ip);
  139. //初始化套接字DLL
  140. WSADATA wsa;
  141. if(WSAStartup(MAKEWORD(2,2),&wsa)!=0){
  142. MessageBox("套接字初始化失败!");
  143. return;
  144. }
  145. //创建套接字
  146. if((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET){
  147. MessageBox("创建套接字失败!");
  148. WSACleanup();
  149. return;
  150. }
  151. ZeroMemory(&serverAddr,sizeof(serverAddr));
  152. serverAddr.sin_family = AF_INET;
  153. serverAddr.sin_addr.S_un.S_addr = htonl(ip);
  154. serverAddr.sin_port = htons(m_port);
  155. //注册感兴趣的网络事件
  156. if(WSAAsyncSelect(sock, m_hWnd, WM_NETWORK, FD_CONNECT | FD_READ | FD_CLOSE)==SOCKET_ERROR){
  157. MessageBox("注册网络事件失败!");
  158. closesocket(sock);
  159. WSACleanup();
  160. }
  161. msg.Format("Connecting to %s:%d/n",inet_ntoa(serverAddr.sin_addr), ntohs(serverAddr.sin_port));
  162. m_allmsg.SetSel(32767,32767);
  163. m_allmsg.ReplaceSel(msg);
  164. if(connect(sock, (struct sockaddr*)&serverAddr, sizeof(serverAddr))==SOCKET_ERROR){
  165. int err = WSAGetLastError();
  166. if(err==WSAEWOULDBLOCK){
  167. msg.Format("Waiting....../n");
  168. m_allmsg.SetSel(32767,32767);
  169. m_allmsg.ReplaceSel(msg);
  170. }else{
  171. MessageBox("无法连接到服务器!");
  172. closesocket(sock);
  173. WSACleanup();
  174. }
  175. }
  176. GetDlgItem(IDC_DISCONNECT)->EnableWindow(TRUE);
  177. GetDlgItem(IDC_SEND)->EnableWindow(TRUE);
  178. GetDlgItem(IDC_CHANGENAME)->EnableWindow(TRUE);
  179. GetDlgItem(IDC_CONNECT)->EnableWindow(FALSE);
  180. GetDlgItem(IDC_IP)->EnableWindow(FALSE);
  181. GetDlgItem(IDC_PORT)->EnableWindow(FALSE);
  182. }
  183. LRESULT CClientDlg::OnNetwork(WPARAM wParam, LPARAM lParam)
  184. {
  185. SOCKET s = (SOCKET)wParam;
  186. WORD netEvent = WSAGETSELECTEVENT(lParam);
  187. WORD error = WSAGETSELECTERROR(lParam);
  188. if(error!=0){
  189. msg.Format("Error code: %d/n",error);
  190. m_allmsg.SetSel(32767,32767);
  191. m_allmsg.ReplaceSel(msg);
  192. if(error==WSAECONNREFUSED){
  193. msg.Format("Connection refused./n");
  194. m_allmsg.SetSel(32767,32767);
  195. m_allmsg.ReplaceSel(msg);
  196. closesocket(sock);
  197. WSACleanup();
  198. GetDlgItem(IDC_DISCONNECT)->EnableWindow(FALSE);
  199. GetDlgItem(IDC_SEND)->EnableWindow(FALSE);
  200. GetDlgItem(IDC_CHANGENAME)->EnableWindow(FALSE);
  201. GetDlgItem(IDC_CONNECT)->EnableWindow(TRUE);
  202. GetDlgItem(IDC_IP)->EnableWindow(TRUE);
  203. GetDlgItem(IDC_PORT)->EnableWindow(TRUE);
  204. }
  205. return -1;
  206. }
  207. switch(netEvent){
  208. case FD_CONNECT:
  209. OnConnect(s);
  210. break;
  211. case FD_READ:
  212. OnRead(s);
  213. break;
  214. case FD_CLOSE:
  215. OnCloseSocket(s);
  216. break;
  217. }
  218. return 0;
  219. }
  220. void CClientDlg::OnConnect(SOCKET s)
  221. {
  222. msg.Format("Connected to %s:%d/n",inet_ntoa(serverAddr.sin_addr),ntohs(serverAddr.sin_port));
  223. m_allmsg.SetSel(32767,32767);
  224. m_allmsg.ReplaceSel(msg);
  225. }
  226. void CClientDlg::OnRead(SOCKET s)
  227. {
  228. static char buf[4096];
  229. int bytes;
  230. bytes = recv(s, buf, sizeof(buf), 0);
  231. if(bytes==SOCKET_ERROR || bytes==0){
  232. msg.Format("Socket error %d/n",WSAGetLastError());
  233. m_allmsg.SetSel(32767,32767);
  234. m_allmsg.ReplaceSel(msg);
  235. closesocket(s);
  236. return;
  237. }
  238. buf[bytes] = '/0';
  239. m_allmsg.SetSel(32767,32767);
  240. m_allmsg.ReplaceSel(buf);
  241. m_allmsg.SetSel(32767,32767);
  242. m_allmsg.ReplaceSel("/n");
  243. }
  244. void CClientDlg::OnCloseSocket(SOCKET s)
  245. {
  246. closesocket(s);
  247. msg = "Connection closed./n ";
  248. m_allmsg.SetSel(32767,32767);
  249. m_allmsg.ReplaceSel(msg);
  250. GetDlgItem(IDC_DISCONNECT)->EnableWindow(FALSE);
  251. GetDlgItem(IDC_SEND)->EnableWindow(FALSE);
  252. GetDlgItem(IDC_CHANGENAME)->EnableWindow(FALSE);
  253. GetDlgItem(IDC_CONNECT)->EnableWindow(TRUE);
  254. GetDlgItem(IDC_IP)->EnableWindow(TRUE);
  255. GetDlgItem(IDC_PORT)->EnableWindow(TRUE);
  256. WSACleanup();
  257. }
  258. void CClientDlg::OnBnClickedSend()
  259. {
  260. UpdateData(TRUE);
  261. int bytes;
  262. bytes = send(sock,(const char*)m_message,m_message.GetLength(),0);
  263. if(bytes==SOCKET_ERROR){
  264. int error = WSAGetLastError();
  265. if(error==WSAEWOULDBLOCK){
  266. msg = "Send failed for message: ";
  267. msg+=m_message;
  268. }else{
  269. msg.Format("Connection is down.");
  270. }
  271. m_allmsg.SetSel(32767,32767);
  272. m_allmsg.ReplaceSel(msg);
  273. }
  274. }
  275. void CClientDlg::OnBnClickedDisconnect()
  276. {
  277. shutdown(sock,SD_SEND);
  278. }
  279. void CClientDlg::OnClose()
  280. {
  281. //MessageBox("close");
  282. closesocket(sock);
  283. WSACleanup();
  284. CDialog::OnClose();
  285. }
  286. void CClientDlg::OnBnClickedQuit()
  287. {
  288. SendMessage(WM_CLOSE);
  289. }
  290. void CClientDlg::OnBnClickedChangeName()
  291. {
  292. UpdateData(TRUE);
  293. char buf[100];
  294. sprintf(buf,"name %s",m_nickname);
  295. if(send(sock,buf,strlen(buf),0)==SOCKET_ERROR){
  296. MessageBox("发送改名命令失败!");
  297. return;
  298. }
  299. }

基于WSAAsyncSelect模型实现的聊天室图形客户端

基于WSAAsyncSelect模型实现的聊天室图形客户端相关推荐

  1. 使用socket实现基于select模型的网络聊天室

    假期闲来无事,便写了个小小的网络聊天室程序.以前一直都是写MFC的有界面的程序,时间长了,便失去了兴趣,感觉有些东西经过MFC的封装,反而失去了意义,让人学不到东西,所以,丢开MFC那层的东西,直接使 ...

  2. Linux下基于socket和多线程的聊天室小程序

    转载:http://blog.csdn.net/robot__man/article/details/52460733 要求:基于TCP编写,一个聊天室最多100人.  客户端:  1.用户需要登录, ...

  3. 基于TCP的网络实时聊天室(socket通信案例)

    开门见山 一.数据结构Map 二.保证线程安全 三.群聊核心方法 四.聊天室具体设计 0.用户登录服务器 1.查看当前上线用户 2.群聊 3.私信 4.退出当前聊天状态 5.离线 6.查看帮助 五.聊 ...

  4. 基于UDP/IP协议的聊天室

    基于TCP/IP通信协议的聊天室 概述: 基于TCP/IP通信协议的聊天室是通过服务端/客户端的模式进行的,必须是服务端开启之后,客户端通过获取服务端的ip和端口号并连接之后才能进行信息的共享,具体的 ...

  5. 可以发送图片文件的php聊天室,基于 Swoole 开发实时在线聊天室(十四):发送图片消息...

    基于 Swoole 开发实时在线聊天室(十四):发送图片消息 由 学院君 创建于1年前, 最后更新于 1年前 版本号 #1 2055 views 0 likes 0 collects 上篇教程我们演示 ...

  6. 基于SSM的Web网页聊天室系统设计与实现 毕业论文+项目源码及数据库文件、

    下载地址:https://download.csdn.net/download/ouyangxiaobai123/22679732 项目介绍: 基于SSM的Web网页聊天室系统设计与实现 毕业论文+项 ...

  7. 视频教程-基于Java的WebSocket的聊天室-Java

    基于Java的WebSocket的聊天室 多年 Java 企业级应用开发工作经验,曾参与中国人寿.华夏人寿.泰康人寿.信达财险等保险行业内部业务管理系统以及线上在线产品的开发:参与中国人民银行.清华大 ...

  8. 网络编程-基于MFC的仿QQ聊天室-2020

    基于MFC的仿QQ聊天室(2020) 有幸学习过网络编程的一些知识,出于对编程的热爱,把曾经的一次简单实践编程作业进行了自定义的完成. 编程所需: 编程工具为VS 2010,需要掌握MFC的基本操作以 ...

  9. Linux下后台服务器开发_基于多线程的一对一QQ聊天室

    废话不多说直接上干货 1.目标 在实现回声服务器和客户端后 ,基于多线程设计一对一的聊天室 2.功能 在本机上实现客户端与服务器的实时聊天测试 以达到练习强化socket通信/多线程技术的目的 3.测 ...

最新文章

  1. 高精地图与自动驾驶(上)
  2. 用C#调用Windows API向指定窗口发送按键消息
  3. c语言中div函数,C 库函数
  4. 二叉树初始化_Java实现二叉树
  5. ExtJs 3.1 XmlTreeLoader Example Error
  6. Android 显示全文折叠控件
  7. 在google play开放平台上closed texting如何删除_“爷青回”!如何抢先体验《英雄联盟》手游?这份攻略送给你...
  8. JS面向对象程序设计(OOP:Object Oriented Programming)
  9. batchsize一定是2的幂_学习率和batchsize如何影响模型的性能?
  10. db2 查看表结构_数据库结构文档的生成利器
  11. 【PAT甲】1001 A+B Format (20分) 格式化输出
  12. np.roll()的理解和用法
  13. 工作日志之MTK刷机
  14. matlab中函数迭代法,Matlab 数值计算----斯特芬森加速迭代法
  15. js获取USB扫码枪数据
  16. 微信小程序重新发起请求加载页面
  17. 对java导出PDF进行图片,(图片/文字)水印,页眉页脚的添加
  18. Linux系统用C语言设计酒店管理系统
  19. 一起学英语-英语名词,代词,动词辨析,混合词序,原级比较,形容词副词比较,多音节形容词,接词连词冠词,动词时态
  20. [RK3288][Android6.0] USB OTG模式及切换

热门文章

  1. Filter_细节_web.xml配置方式
  2. eureka架构图原理
  3. JavaScript中替换字符串中的所有小数点
  4. 200730学习日报6字符串
  5. 洛谷 P1983 车站分级
  6. Spark学习之Spark调优与调试(7)
  7. 安装在谷歌axure小工具
  8. 有没有通过代码退出程序的方法--官方解答
  9. row_number() over (partition by....order by...)用法 分组排序
  10. No symbols have been loaded for this document