您的位置:首页 > 理论基础 > 计算机网络

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;
}
}


运行效果:



在另外一台电脑上同时运行一个客户端程序,会看到程序一打开就会载入与此客户端相同的数据;而且当在任意客户端上添加数据时,会看到其他对话框中也添加了此条数据。

原因是:当某个对话框添加数据后,同时会向服务器发送此条消息,服务器作为中转站又向所有在线的客户端发送消息,从而使得各个客户端的数据同步。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: