服务器端
CListenSocket
m_listenSocket; //监听套接字
点击启动服务按键
//创建监听套接字,激发FD_ACCEPT事件,默认端口5088
BOOL bFlag=
m_listenSocket.
Create(5088,SOCK_STREAM,FD_ACCEPT);
m_listenSocket.
Listen(1);
在OnAccept()函数中
//侦听到连接请求,调用Accept函数
CNewSocket*
pSocket = new CNewSocket();
if(
Accept(*
pSocket)) //接受连接
{
pSocket->
AsyncSelect(FD_READ);
//
有读事件的时候,Socket中的OnReceive事件就会触发
m_pSocket=pSocket; //记录当前通信Socket
}
else
delete pSocket;
CAsyncSocket::OnAccept(nErrorCode);
在OnReceive()函数中
m_nLength=
Receive(m_szBuffer,sizeof(m_szBuffer),0);
// 直接转发消息
AsyncSelect(FD_WRITE);
//触发OnSend函数
CAsyncSocket::OnReceive(nErrorCode);
在OnSend()函数中,发送接收到的数据
char m_sendBuffer[4096];
//消息缓冲区
memcpy(m_sendBuffer,"服务器转发:",24);
strncat(m_sendBuffer,m_szBuffer,m_nLength);
Send(m_sendBuffer,sizeof(m_sendBuffer));
//发送数据
AsyncSelect(FD_READ);
//触发OnReceive函数
CAsyncSocket::OnSend(nErrorCode);
客户端
CClientSocket
m_clientSocket;
点击连接按键,执行OnConnect函数
m_clientSocket.ShutDown(2);
m_clientSocket.m_hSocket=INVALID_SOCKET;
m_clientSocket.m_bConnected=FALSE;
CAddrDlg
m_Dlg;
m_szPort=5088;//默认端口5088
if (
m_Dlg.DoModal()==IDOK && !
m_Dlg.m_Addr.IsEmpty())
//填写IP地址,点击确认键
{
memcpy(m_szServerAdr,
m_Dlg.m_Addr,sizeof(m_szServerAdr));
//建立计时器,每1秒尝试连接一次,直到连上或TryCount>10
SetTimer(1,1000,NULL);
TryCount=0;
}
在定时器处理函数中
BOOL bFlag=
m_clientSocket.
Create(0,SOCK_STREAM,FD_CONNECT);
//创建套接字
m_clientSocket.
Connect(m_szServerAdr,m_szPort); //连接服务器
TryCount++; //连接次数加1
if (TryCount >=10 || m_clientSocket.m_bConnected) //如果已经连接或连接超时
{
KillTimer(1); //关闭定时器
if (TryCount >=10) //连接超时
{
AfxMessageBox("连接失败!");
GetDlgItem(IDC_CONNECT)->EnableWindow(true);
}
return;
}
至此连接结束,接下来就是发送数据,填好发送的信息后,点击发送按键,执行OnSend函数
if (
m_clientSocket.m_bConnected)
//先检查是否已经连接
{
//获取用户数据的待发送信息
m_clientSocket.m_nLength=m_MsgS.GetWindowText(m_clientSocket.m_szBuffer,
sizeof(m_clientSocket.m_szBuffer));
//触发Socket的OnSend函数
m_clientSocket.AsyncSelect(FD_WRITE);
}
在
CClientSocket和
CTransClientDlg这两个类中都有OnConnect、OnSend函数,前面说的都是
CTransClientDlg
这个类中的函数。下面用到的是
CClientSocket
中的
AsyncSelect括号内的参数是诸如FD_CONNECT、FD_WRITE、FD_READ这些常量
。
AsyncSelect(FD_READ)投递一个“读“的事件,准备接收,如果有读事件的时候,那么OnReceive事件就会触发,
如果传入FD_WRITE就投了一个“写”事件,那么当发送数据的时候,你的OnSend事件就会触发。可以用|来表示需要监听多个事件。
在触发的OnSend函数中发送数据
Send(m_szBuffer,m_nLength,0);//发送数据
m_nLength=0;
memset(m_szBuffer,0,sizeof(m_szBuffer));//清除缓冲区数据
//继续提请一个"读"的网络事件,如果有读事件的时候,那么OnReceive事件就会触发
AsyncSelect(FD_READ);
CAsyncSocket::OnSend(nErrorCode);
因为在之前调用了AsyncSelect(FD_READ),当收到服务器信息后,就会执行OnReceive函数
m_nLength=
Receive(m_szBuffer,sizeof(m_szBuffer),0);
//接收数据
pDlg->m_MsgR.InsertString(0,m_szBuffer);//列表框添加接收的数据
memset(m_szBuffer,0,sizeof(m_szBuffer));//清除缓冲区数据