首先建立对话框,上面含有编辑框,启动按钮,取消,发送按钮。
关联变量接收编辑框CString m_rxdata;发送编辑框CString m_txdata;
在StdAfx.h文件中包含头文件#include<afxsock.h> //include MFC sock extensions
定义宏#define WM_CLIENT_ACCEPT WM_USER+101
#define WM_CLIENT_READCLOSE WM_USER+102
并定义一个结构体
typedef struct ZyMsg
{
char msg[100];
int i;
}Msg;
在头文件中定义如下变量,并定义接收函数并自己添加消息映射
Msg msg;
BOOL BindOK;
SOCKADDR_IN m_sockServerAddr;
SOCKET ServerSocket;
SOCKET Client;
LRESULT OnReadClose(WPARAM wParam,LPARAM lParam);
LRESULT OnAccept(WPARAM wParam,LPARAM lParam);
源文件中消息映射
ON_MESSAGE(WM_CLIENT_ACCEPT,OnAccept)
ON_MESSAGE(WM_CLIENT_READCLOSE,OnReadClose)
添加启动按钮和发送按钮的消息响应
然后添加代码
void CServerDlg::ServerInit() //服务器初始化
{
//初始化绑定服务器
WSADATA wsaData;
int ErrorCode;
if(WSAStartup(MAKEWORD(2,1),&wsaData)) //调用Windows Sockets DLL
{
MessageBox("WinSock 无法初始化!");
WSACleanup();
return ;
}
m_rxdata+="服务器开始创建SOCKET";
UpdateData(FALSE); //将变量中数据更新到编辑框
ServerSocket=socket(PF_INET,SOCK_STREAM,0); //创建服务器端Socket,类型为SOCK_STREAM,面向连接的通信
if(INVALID_SOCKET == ServerSocket)
{
MessageBox("无法创建服务器socket!");
return ;
}
m_sockServerAddr.sin_addr.S_un.S_addr=INADDR_ANY; //向所有的IP地址发送信息
m_sockServerAddr.sin_family=AF_INET;
m_sockServerAddr.sin_port=htons(8001);
//与选定的端口绑定
if(SOCKET_ERROR==bind(ServerSocket,(LPSOCKADDR)&m_sockServerAddr,sizeof(m_sockServerAddr)))
{
MessageBox("无法绑定服务器!");
return ;
}
m_rxdata+="/n服务器端口8001 ";
UpdateData(FALSE); //将变量中数据更新到编辑框
//产生相应传递给窗口的消息为WM_SERVER_ACCEPT,这是自定义消息
ErrorCode=WSAAsyncSelect(ServerSocket,m_hWnd,WM_CLIENT_ACCEPT,FD_ACCEPT);
if(SOCKET_ERROR == ErrorCode)
{
// MessageBox("WSAAsyncSelect 设定失败!--用于连接请求的消息!");
return ;
}
//开始监听客户连接请求
if(SOCKET_ERROR == listen(ServerSocket,3))
{
// MessageBox("服务器监听失败!");
return ;
}
BindOK=TRUE; //success
m_rxdata+="/n服务器绑定监听成功";
UpdateData(FALSE); //将变量中数据更新到编辑框
return ;
}
void CServerDlg::OnStart() //启动
{
// TODO: Add your control notification handler code here
ServerInit(); //服务器初始化
}
void CServerDlg::OnBtnSend() //发送
{
// TODO: Add your control notification handler code here
//发送数据
if(!BindOK)
{
MessageBox("无工作站连接,或服务器未启动!");
return ;
}
UpdateData(TRUE); //将编辑框中数据更新到变量
strcpy((char*)msg.msg,(LPCTSTR)m_txdata); //将发送编辑框中的数据拷贝到结构体msg中
msg.i=0; //变量清零
if(SOCKET_ERROR==send(Client,(char*)&msg,sizeof(msg),0)) // recv(ServerSocket,buf,sizeof(buf),0);
{
MessageBox("发送数据错误!");
return ;
}
else
{
m_rxdata+=m_txdata;
}
m_txdata.Empty(); //发送编辑框清空
UpdateData(FALSE); //将变量中的值更新到编辑框
((CEdit*)GetDlgItem(IDC_BTN_SEND))->SetActiveWindow(); //
}
void CServerDlg::OnExit() //退出
{
// TODO: Add your control notification handler code here
WSACleanup();
OnOK();
}
//自定义接收客户机请求的消息 ON_MESSAGE(WM_CLIENT_ACCEPT,OnAccept)
LRESULT CServerDlg::OnAccept(WPARAM wParam, LPARAM lParam)
{
if(WSAGETSELECTERROR(lParam))
{
MessageBox("Error detected to entry into OnServerAccept!");
return 0L;
}
if(WSAGETSELECTEVENT(lParam)==FD_ACCEPT) //如果
{
Client = accept(ServerSocket,(LPSOCKADDR)&m_sockServerAddr,0);
if(INVALID_SOCKET == Client)
{
MessageBox("Server socket failed to accept connection!");
return 0L;
}
WSAAsyncSelect(Client,m_hWnd,WM_CLIENT_READCLOSE,FD_READ | FD_CLOSE);
BindOK=TRUE;
}
m_rxdata+="/n有工作站连接!";
UpdateData(FALSE); //将变量中数据更新到编辑框
return 0L;
}
//自定义的关闭与缓冲区有消息
LRESULT CServerDlg::OnReadClose(WPARAM wParam, LPARAM lParam)
{
if(!BindOK)
{
m_rxdata+="/n有数据到达,但没有工作站信息";
UpdateData(FALSE); //将变量中数据更新到编辑框
}
CString str;
switch(WSAGETSELECTEVENT(lParam))
{
case FD_READ:
if(SOCKET_ERROR == recv(Client,(char *)&msg,sizeof(msg),0))
{
m_rxdata+="/n接受数据发生错误";
UpdateData(FALSE); //将变量中数据更新到编辑框
return 0L;
}
str.Format("%s",msg.msg);
m_rxdata+=str;
UpdateData(FALSE); //将变量中数据更新到编辑框
break;
case FD_CLOSE:
str=_T("/n工作站退出");
m_rxdata=str;
closesocket(Client);
BindOK=FALSE;
UpdateData(FALSE); //将变量中数据更新到编辑框
break;
}
return 0L;
}