一般的TCP的连接及创建

来源:互联网 发布:app软件说明书 编辑:程序博客网 时间:2024/06/03 07:35

一、创建服务端(Server)和客户端(Client)

初学时可以以对话框的形式创建两个工程分别定义为:ServerClient

服务端的功能:用来进行数据的保存(保存形式可以是数据库;如果是简单测试用,则用CList或者CArray来模拟数据库的功能)以及处理客户端传送来的指令的处理,当然还需要人员的维护数据。

客户端的功能:则是用户的输入、删除、修改,浏览等功能,是用户体验的平台。

 

二、简单的“员工信息系统的服务端和客户端”

1.在服务器端:创建两个套接字(CSocket:阻塞的通讯类),一个用于监听(CListenSocket),一个用于保存数据以及对用户传来的指令进行处理(CClientSocket)。

    a.监听处理时,重载虚函数OnAccept()

void CListenSocket::OnAccept(int nErrorCode)

{//每次当有客户端启动时,在堆内申请创建CClientSocket;

CClientSocket *pSock = new CClientSocket;

if (!Accept(*pSock))

delete pSock;

CSocket::OnAccept(nErrorCode);

}

b.然后在CClientSocket中重载OnReceive(),OnClose(),其中OnReceive接收客户端传来的指令和传进的数据,OnClose则是当其中一个或多个客户端关闭时释放(deletenew出来的内存(注意:在编码客户端程序时,应当将指令的类型和数据内容一起传过来,并先执行添加协议,但执行完整的添加协议需要两次接受数据(OnReceive),所以在客户端添加(Add),应当注意传的排序,先指令后数据,后面会讲到)

void CClientSocket::OnReceive(int nErrorCode)

{//接收客户端传来的指令和传进的数据

int nCmd = 0, nLen = 0;

if (Receive(&nCmd, sizeof(nCmd)) <= 0) //接受的指令类型;

return;

switch (nCmd)

{

case INF_ADD:

AddData(); //定义数据添加协议;

break;

case INF_BROW:

Browse(); //定义浏览数据协议;

break;

}

CSocket::OnReceive(nErrorCode);}

 

void CClientSocket::OnClose(int nErrorCode)

{//一个或多个客户端关闭时释放(deletenew出来的内存

delete this;

CSocket::OnClose(nErrorCode);}

c.定义协议的内容:

void CClientSocket::AddData()

{ //添加数据的协议处理;

SData data;

if (Receive(&data, sizeof(data)) <= 0)

return;

theApp.m_list.AddTail(data);  //在CList的末尾添加元素;

}

 

void CClientSocket::Browse()

{   //浏览数据的协议处理,先发总数在逐步发送具体数据;

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

}

}

 

 

 

1.在客户端:

BOOL CSK_nTCP_clientDlg::OnInitDialog()

{

CDialogEx::OnInitDialog();

m_sock.Create();

if (!m_sock.Connect(_T("169.254.216.64"), 8400))

{

CString str;

str.Format(_T("连接失败:无法连接服务器,请检查你的网络连接;\r\n%d"), GetLastError());

AfxMessageBox(str);

EndDialog(IDCANCEL);

return FALSE;

}

m_list.InsertColumn(0, _T("工号"), 0, 100);

m_list.InsertColumn(1, _T("姓名"), 0, 100);

m_list.InsertColumn(2, _T("工资"), 0, 100);

OnRefresh();

return TRUE;  

}

 

 

void CSK_nTCP_clientDlg::OnPaint()

{

CDialogEx::OnPaint();}

 

void CSK_nTCP_clientDlg::OnBnClickedAdd()

{//先发送协议号编号再发送一条信息数据到服务器端;

int nCmd = INF_ADD;

m_sock.Send(&nCmd, sizeof(nCmd));

SData data = { (int)GetDlgItemInt(IDC_NUMB) };

GetDlgItemText(IDC_NAME, data.sName, sizeof(data.sName));

CString str;

GetDlgItemText(IDC_SALA, str);

data.fSala = (float)_wtof(str);

m_sock.Send(&data, sizeof(data));

OnRefresh();

}

 

 

void CSK_nTCP_clientDlg::OnRefresh()

// 发送完协议编号后,先接受数据总数再逐条接受每条具体数据;

int nCmd = INF_BROW;

m_sock.Send(&nCmd, sizeof(nCmd));

int nCount = 0, i = 0;

m_sock.Receive(&nCount, sizeof(nCount));

m_list.DeleteAllItems();

SData data;

CString str;

while (i < nCount)

{   //从服务端接受每条数据,并将内容插入到列表控件中显示;

m_sock.Receive(&data, sizeof(data));

str.Format(_T("%d"), data.nNumb);

m_list.InsertItem(i, str);

m_list.SetItemText(i, 1, data.sName);

str.Format(_T("%0.2f"), data.fSala);

m_list.SetItemText(i, 2, str);

i++;

}

}

(PS:注意以上不是完整的代码,仅提供参考的思路,路是自己走的,作为一名程序要有独立的思考能力!!)

0 0