《MFC网络通信》Part 2 简单TCP通信
2016-03-20 13:02
471 查看
《MFC网络通信》Part 2 简单TCP通信
一般TCP通信软件都分为服务器端和客户端。
TCP服务器端由一个侦听Socket和多个用于应答的Socket组成,每个应答Socket与客户端建立一对一的数据流通道。
客户端程序只包含一个链接Socket,它在成功连接服务器后与某一个应答Socket经行一对一的数据通信。
因此,我们需要创建两个程序,分别是服务器程序和客户端程序。分别命名为Server和Client。
第一步:创建Server服务器程序。
1、新建普通的MFC(exe)对话框程序,程序命名为Server,第二步中勾选Window Sockets。
2、创建工程完毕后,记得查看stdafx.h中的预编译头文件,检查是否包括:
5、同样的方法创建一个CSocket类的派生类CClientSocket。
6、在CServerApp类的头文件中添加一个指针链表类型的成员变量。
7、在创建的CListenSocket类中添加虚函数OnAccept,用于截获客户端的连接。
8、在CClientSocket类中添加虚函数OnReceive,用于截获客户端发来的网络数据。
9、在CClientSocket类中添加虚函数OnClose,用于监测客户端是否断开了连接。
12、编译运行即可,接下来创建客户端程序。
第二步:创建Client服务器程序。
1、创建Client工程,记得第二部勾选勾选Window Sockets。
2、主对话框中添加控件,如下图所示。
3、修改控件的属性列表。
4、创建CSocket的派生类CConnectSocket,过程同第一步:创建Server服务器程序——第4步相同。
5、在CConnectSocket类中添加虚函数OnReceive,用于截获服务器发来的网络数据。
9、编译运行,首先要开启编译好的服务器端程序,再在一台或多台计算机开启客户端程序经行调试。
运行结果如下:
一般TCP通信软件都分为服务器端和客户端。
TCP服务器端由一个侦听Socket和多个用于应答的Socket组成,每个应答Socket与客户端建立一对一的数据流通道。
客户端程序只包含一个链接Socket,它在成功连接服务器后与某一个应答Socket经行一对一的数据通信。
因此,我们需要创建两个程序,分别是服务器程序和客户端程序。分别命名为Server和Client。
第一步:创建Server服务器程序。
1、新建普通的MFC(exe)对话框程序,程序命名为Server,第二步中勾选Window Sockets。
2、创建工程完毕后,记得查看stdafx.h中的预编译头文件,检查是否包括:
#include <afxsock.h><span style="white-space:pre"> </span>//MFC socket extensions3、查看类视图中的CServerApp类中的函数InitInstance函数是否自动生成以下代码:
BOOL CServerApp::InitInstance() { if (!AfxSocketInit()) { AfxMessageBox(IDP_SOCKETS_INIT_FAILED); return FALSE; } // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need. ……4、在Server工程中创建一个CSocket类的派生类CListenSocket(Name中的1忽略掉):
5、同样的方法创建一个CSocket类的派生类CClientSocket。
6、在CServerApp类的头文件中添加一个指针链表类型的成员变量。
class CServerApp : public CWinApp { public: CPtrList m_list;//公有成员变量存储与客户端通信的CClientSocket对象的地址 ……
7、在创建的CListenSocket类中添加虚函数OnAccept,用于截获客户端的连接。
// CListenSocket member functions #include "ClientSocket.h" extern CServerApp theApp; void CListenSocket::OnAccept(int nErrorCode) { // TODO: Add your specialized code here and/or call the base class //新建一个CClientSocket CClientSocket *pSock = new CClientSocket; if(Accept(*pSock)) theApp.m_list.AddTail(pSock); else delete pSock; CSocket::OnAccept(nErrorCode); }
8、在CClientSocket类中添加虚函数OnReceive,用于截获客户端发来的网络数据。
extern CServerApp theApp; void CClientSocket::OnReceive(int nErrorCode) { // TODO: Add your specialized code here and/or call the base class char s[2084]; int nLen = Receive(s,sizeof(s)-1); if(nLen<0) return ; s[nLen] = 0; CString szIP; UINT nPort; GetPeerName(szIP,nPort); CString str; str.Format("%d-%d对所有人说:\r\n%s\r\n",szIP,nPort,s); CPtrList& list = theApp.m_list; POSITION pos = list.GetHeadPosition(); while (pos) { //将一个客户端发来的聊天文字,群发给所有其他客户端 CClientSocket* pSock = (CClientSocket*)list.GetAt(pos); //不对刚发出的聊天文字的客户端转发 if (pSock!=this) pSock->Send(str,str.GetLength()); list.GetNext(pos); } CSocket::OnReceive(nErrorCode); }
9、在CClientSocket类中添加虚函数OnClose,用于监测客户端是否断开了连接。
void CClientSocket::OnClose(int nErrorCode) //用于检测某个客户端是否断开了连接 { // TODO: Add your specialized code here and/or call the base class //将与客户端断开连接的CClientSocket对象地址从链表中移除 CPtrList &list= theApp.m_list; POSITION pos =list.GetHeadPosition(); while (pos) { if (list.GetAt(pos)==this) { list.RemoveAt(pos); break; } list.GetNext(pos); } //清理对象占用的堆空间 delete this; CSocket::OnClose(nErrorCode); }10、主对话框类CServerDlg的头文件中,添加CListenSocket类型的成员变量m_sock。
#include "ListenSocket.h" class CServerDlg : public CDialog { CListenSocket m_sock;//添加CListenScoket类型的成员变量 ……11、修改主对话框CServerDlg中的初始化函数,创建Socket并开始侦听。
BOOL CServerDlg::OnInitDialog()//初始化函数代码,创建socket并开始侦听 { CDialog::OnInitDialog(); if(m_sock.Create(8118)) m_sock.Listen(); else { CString str; str.Format("Socket Create Error.%d",GetLastError()); AfxMessageBox(str); } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here return TRUE; // return TRUE unless you set the focus to a control }
12、编译运行即可,接下来创建客户端程序。
第二步:创建Client服务器程序。
1、创建Client工程,记得第二部勾选勾选Window Sockets。
2、主对话框中添加控件,如下图所示。
3、修改控件的属性列表。
控件类型 ID CaptionStyle Edit IDC_HIST 多行、垂直滚动条、只读(去掉自动水平滚动条) Edit IDC_INPUT Button IDOK 发送(&S) Button IDCANCEL 关闭
4、创建CSocket的派生类CConnectSocket,过程同第一步:创建Server服务器程序——第4步相同。
5、在CConnectSocket类中添加虚函数OnReceive,用于截获服务器发来的网络数据。
void CConnectSocket::OnReceive(int nErrorCode) { // TODO: Add your specialized code here and/or call the base class char s[2048]; int nLen = Receive(s,sizeof(s)-1); if(nLen<=0) return ; s[nLen]=0; CWnd* pWnd = AfxGetMainWnd(); CEdit* pEdit = (CEdit*)pWnd->GetDlgItem(IDC_HIST); pEdit->SetSel(pEdit->GetWindowTextLength(),-1); pEdit->ReplaceSel(s); CSocket::OnReceive(nErrorCode); }<span style="color:#3333ff;"> </span>6、主对话框类头文件中添加一个CConnectSocket类型的成员变量。
#include "onnectSocket.h"//由于少写了个C class CClientDlg : public CDialog { CConnectSocket m_sock;7、修改主对话框中的初始化函数代码。
// CClientDlg message handlers BOOL CClientDlg::OnInitDialog() { CDialog::OnInitDialog(); m_sock.Create(); if (!m_sock.Connect("192.168.1.46",8118))<span style="white-space:pre"> </span>//此处的IP地址记得写成自己电脑的IP { //连接服务器端运行的主机IP地址 CString str; str.Format("连接失败:%d",GetLastError()); AfxMessageBox(str); } ……8、主对话框的类中,添加“发送(&S)”按钮的消息映射函数OnOK。
void CClientDlg::OnOK() { // TODO: Add extra validation here CString szText; GetDlgItemText(IDC_INPUT,szText); if(m_sock.Send(szText,szText.GetLength())>0) { CEdit *pEdit = (CEdit*)GetDlgItem(IDC_HIST); pEdit->SetSel(pEdit->GetWindowTextLength(),-1); pEdit->ReplaceSel("\n你对所有人说:\r\n"+szText+"\r\n"); } //CDialog::OnOK(); }
9、编译运行,首先要开启编译好的服务器端程序,再在一台或多台计算机开启客户端程序经行调试。
运行结果如下:
相关文章推荐
- 神经网络可以拟合任意函数的视觉证明A visual proof that neural nets can compute any function
- 4000 基于DES加密的TCP聊天程序
- 计算机网络中一些名词解释(一)
- HttpClient 和 HttpURLConnection 的使用
- H5学习系列之文件读取API--本文转自http://blog.csdn.net/jackfrued/article/details/8967667
- linux 网络源码布局
- C++ 用libcurl库进行http通讯网络编程
- 基础的http协议构成
- TCP三次握手和四次挥手
- HTTP状态码整理
- 一些我推荐的和想上的网络课程(Coursera, edX, Udacity,MIT OCW)
- CentOS图形配置网络
- 虚拟化网络之OpenvSwitch(一)
- Tcp实现简单的大小写转换功能
- AsyncHttpClicent框架
- Tcp通讯协议
- HttpClient使用详解
- 搭建TCP服务器环境和jmeter测试TCP协议
- 神经网络模型算法与生物神经网络的最新联系
- BZOJ2132