MFC网络编程(三):一般TCP通信
2017-10-23 21:10
204 查看
介绍
上一篇所实现的TCP程序没有包括通信协议的内容,因此服务器和客户端只能进行简单的信息交流。当交互的要求比较多的时候(比如说客户端不只是发送文本信息,同时还要求能够对服务器数据进行增、删、改等操作),通常会定义一些通信协议。通信协议由命令号和附加数据所组成。命令号也叫协议号,就是用一个数字或者字符串通知对方执行一个对应的命令;附加数据包含与某个命令相关的数据。
通信协议的使用使客户端和服务器的交流更有条理性。
实例
创建一个C/S结构的网络版信息管理软件
1. 首先,定义需要的协议编号和数据信息:enum { //协议编号 INF_ADD=0x1234, INF_BROW, INF_DEL, INF_MOD, INF_FIND }; struct SData { //传输的数据 int nNumb; char sName[20]; float fSala; }
将以上代码同时添加到服务器和客户端的App类的头文件中;
2. 分别开发服务器程序和客户端程序:
A.服务器程序
(1)在App头文件中添加一个变量,用于管理数据:
CList<SData,SData> m_list;
(2)添加两个CSocket类,用于侦听和应答:
在CListenSocket类中:
添加虚函数OnAccept用于获得客户端的连接;
在CCLientSocket类中:
添加虚函数OnClose,用于检查客户端的断开;
添加虚函数OnReceive,用于接收客户端命令并做出相应的反应:
void CClientSocket::OnReceive(int nErrorCode) { int nCmd; Receive(&nCmd,sizeof(nCmd));//接受命令号 switch (nCmd) { //根据不同的命令号做出相应的操作 case INF_ADD: AddData(); break; case INF_BROW: Browse(); break; } CSocket::OnReceive(nErrorCode); } //以下为自定义的函数 void CClientSocket::AddData(void) { //添加数据 SData data; Receive(&data,sizeof(data));//接收客户端的数据 theApp.m_list.AddTail(data);//存入列表 } void CClientSocket::Browse(void) { //浏览数据 int nCount=theApp.m_list.GetCount(); Send(&nCount,sizeof(nCount));//将列表中的信息条数先发给客户端 POSITION pos=theApp.m_list.GetHeadPosition(); while(pos) { SData data=theApp.m_list.GetNext(pos); Send(&data,sizeof(data));//再逐条发送信息 } }
(3)在主对话框中定义CListenSocket的成员变量,并在初始化函数中创建端口并调用侦听函数进行侦听。
B.客户端程序
(1)编辑客户端界面;
(2)在主对话框类中添加CSocket类的成员变量,并在初始化函数中创建端口并调用Connect函数连接服务器;
(3)为“添加”按钮建立消息响应函数,同时在初始化函数中添加OnRefresh函数,用于每次登录后从服务器处获得信息更新显示列表:
void C客户端Dlg::OnBnClickedAdd() { int nCmd=INF_ADD; m_sock.Send(&nCmd,sizeof(nCmd));//先发送命令:添加数据 //获取要添加的数据并存入SData中,用于发送 SData data={GetDlgItemInt(IDC_NUMB)}; GetDlgItemText(IDC_NAME,data.sName,sizeof(data.sName)); CString str; GetDlgItemText(IDC_SALA,str); data.fSala=(float)atof(str);//将string型转化成float型数据 //发送信息 m_sock.Send(&data,sizeof(data)); //将添加的一条信息发给服务器后,更新列表 OnRefresh(); } void C客户端Dlg::OnRefresh() { int nCmd=INF_BROW; m_sock.Send(&nCmd,sizeof(nCmd));//发送浏览命令 int nCount=0,i=0; m_sock.Receive(&nCount,sizeof(nCount));//得到新列表的信息条数 list.DeleteAllItems();//列表控件清空 SData data; CString str; while(i<nCount) { //逐条接受数据,并显示在列表中 m_sock.Receive(&data,sizeof(data)); str.Format("%d",data.nNumb); list.InsertItem(i,str); list.SetItemText(i,1,data.sName); str.Format("%0.2f",data.fSala); list.SetItemText(i,2,str); ++i; } }
运行效果:
在另外一台电脑上同时运行一个客户端程序,会看到程序一打开就会载入与此客户端相同的数据;而且当在任意客户端上添加数据时,会看到其他对话框中也添加了此条数据。
原因是:当某个对话框添加数据后,同时会向服务器发送此条消息,服务器作为中转站又向所有在线的客户端发送消息,从而使得各个客户端的数据同步。
相关文章推荐
- MFC网络编程(二):简单TCP通信
- MFC学习笔记之——>MFC下的TCP通信的建立
- 基于socket通信的,利用MFC实现TCP通信的C/S架构程序
- [MFC]TCP通信的简单实现
- MFC学习笔记之——>MFC下的TCP通信的建立
- Java基础—网络编程【OSI/RM TCP/IP】【网络通信三要素】【UDP传输 & TCP传输】【DNS域名解析】
- Python socket网络编程TCP/IP服务器与客户端通信
- [置顶] 网络编程中最简单的TCP通信(CS模型)
- Java 网络编程(五) 使用TCP/IP的套接字(Socket)进行通信
- [网络编程]——网络编程_TCP_Socket通信_聊天室.雏形
- 记mfc父子控件通信的一般方法
- C#TCP Socket网络编程(异步通信方式)
- Java基础—网络编程【OSI/RM TCP/IP】【网络通信三要素】【UDP传输 & TCP传输】【DNS域名解析】
- MFC网络编程TCP/IP的服务器与客户端代码
- Java 网络编程(五) 使用TCP/IP的套接字(Socket)进行通信
- Java基础—网络编程【OSI/RM TCP/IP】【网络通信三要素】【UDP传输 & TCP传输】【DNS域名解析】
- 再次深入理解TCP网络编程中的send和recv(TCP传输的一般过程抓包演示)
- Java 网络编程(五) 使用TCP/IP的套接字(Socket)进行通信
- ubuntu命令行常用命令之远程服务器TCP通信
- TCP/IP 是用于因特网 (Internet) 的通信协议。