介绍
上一篇介绍了基于UDP的通信过程,这里总结一下TCP通信的基本内容,并实现一个一个简单版的聊天室软件。
TCP通信软件必须依据C/S架构开发,也就是说,要有服务器端和客户端两个部分。
服务器端程序包含一个侦听Socket和多个应答Socket。通俗地讲,侦听Socket是公司的前台接待,接到客户后将其分配给应答Socket;应答Socket相当于客户经理,与客户端一对一地进行沟通。
实例:一个简单的聊天室软件
首先创建项目名为“Server”和“Client”的两个对话框程序,然后分别进行代码编写。
1.服务器端程序
(1)创建两个CSocket的派生类:
class CListenSocket:public CSocket //负责侦听
class CClientSocket:public CSocket //负责应答
(2)在App类头文件中添加一个指针链表的成员变量,用于存储与客户端通信的CClientSocket对象的地址:
CPtrList m_list;
(3)编写两个Socket类中的用于通信的虚函数:
A.CListenSocket类:
#include "SockC.h"
void CSockL::OnAccept(int nErrorCode)//用于截获客户端的连接
{
//新建一个CSocketC对象
CSockC *pSock=new CSockC;
//与新连接的的客户端相关联
if(Accept(*pSock))
//添加进列表
theApp.m_list.AddTail(pSock);
else
delete pSock;
CSocket::OnAccept(nErrorCode);
}
B.CClientSocket类:
void CSockC::OnReceive(int nErrorCode)//用于截获客户端发来的数据
{
char s[2048];
CString sIP;
UINT nPort;
//获得客户端的IP和端口信息
GetPeerName(sIP,nPort);
//获得发来的信息
int nRet=Receive(s,sizeof(s));
if(nRet<=0)
return;
s[nRet]=0;
CString str;
//将发送者的信息、发送的内容进行打包
str.Format("%s 对所有人说:\r\n%s\r\n",sIP,s);
CPtrList &list=theApp.m_list;
POSITION pos=list.GetHeadPosition();
while(pos)
{
//获得所有在线的客户经理
CSockC *pSock=(CSockC*)pList->GetAt(pos);
if(pSock!=this)//不包括发出消息的用户
//客户经理发送消息给对应的在线客户
pSock->Send(str,str.GetLength());
pList->GetNext(pos);
}
CSocket::OnReceive(nErrorCode);
}
void CSockC::OnClose(int nErrorCode)//用于处理客户端断开连接的情况
{
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);
}
(4)在主对话框类中添加CListenSocket类的成员变量,并在初始化函数中创建端口进行侦听:
//在头文件中添加变量
CListenSocket m_sock;
//在初始化函数中创建、侦听,这里可以添加报错提示
m_sock.Create(8888);
m_sock.Listen();
2.客户端程序
(1)首先,编辑好客户端界面资源;
(2)添加一个CSocket类:
class CConnectSocket:public CSocket
(3)添加虚函数OnReceive,用于获取服务器发来的数据:
//获取数据
char s[2048];
int nLen=Receive(s,sizeof(s));
if(nLen<=0)
return;
//下面的代码用于将截获的消息s显示在界面中
...
(4)在主对话框中添加变量并修改初始化函数,添加发送按钮的消息映射函数:
//在头文件中添加变量
CConnectSocket m_sock;
//在初始化函数中实现连接服务器
m_sock.Create();
m_sock.Connect("192.168.1.120",8888);//服务器的IP和设定的端口号
//添加发送按钮的消息响应函数
m_sock.Send(szText,sizeof(szText));//szText为消息文字
3.运行效果
先打开服务器,在打开客户端进行消息输入。