基于socket的网络通信实现(MFC)
2017-02-09 17:02
585 查看
网络通信
本节将基于socket编写服务器端和客户端,实现网络通信。程序采用MFC对话框框架,在visual stdio2012平台上实现。 程序采用面向对象的方法设计,服务器端由CServerDlg构建,客户端由CClientDlg类构建。构建思路如下 服务器端: (一)开启服务器 1.加载套接字库 2.创建套接字 3.获取服务器端所在的IP地址 4.绑定套接字和端口号 5.监听来自客户端的消息 6.设置异步套接字 (二)响应客户端连接与接收信息 当客户端与服务器端建立连接时,服务器端会接收到FD_ACCEPT的事件通知,构建FD_ACCEPT的事件内容 当连接已经建立,服务器可以通过FD_READ事件来接受来自客户端的信息 (三) 发送信息 用户在发送信息的文本框汇中编辑信息,然后单击发送按钮发送信息 服务器端界面如下:
实现代码如下:
void CServerDlg::OnBnClickedStartrun() { // TODO: 在此添加控件通知处理程序代码 //加载套接字库 WORD version = MAKEWORD(2,0); WSADATA wsadata; if(WSAStartup(version, &wsadata)){ MessageBox("加载Winsock dll 失败"); return; } //创建套接字 socket_server = socket(AF_INET, SOCK_STREAM, NULL); if(INVALID_SOCKET == socket_server){ MessageBox("套接字创建失败!"); return; } //获取主机名 char hostname[20] = ""; if(gethostname(hostname, 20)){ MessageBox("主机名获取失败"); return; } //通过主机名来获取记录主机IP的结构 hostent *htent = gethostbyname(hostname); if(htent == NULL){ MessageBox("主机IP获取失败!"); return; } //获取IP地址 LPSTR lpAddr = htent->h_addr_list[0]; IN_ADDR inAddr; memmove(&inAddr, lpAddr,4); CString ipAddress = inet_ntoa(inAddr); //绑定套接字 SOCKADDR_IN addr; memset(&addr, 0, sizeof(SOCKADDR_IN)); //将地址内容清零 addr.sin_family = AF_INET; addr.sin_port = htons(80); addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); if( bind(socket_server, (sockaddr*)&addr,sizeof(sockaddr)) ){ MessageBox("绑定IP和PORT出错"); return; } //监听 if(listen(socket_server,SOMAXCONN)){ MessageBox("异步设置出错"); return; } //设置异步套接字 if( WSAAsyncSelect( socket_server, this->m_hWnd, WM_SOCKET, FD_ACCEPT| FD_READ) ){ MessageBox("异步设置出错"); return; } m_recv += "服务器端已开启,等待客户端连接\r\n"; UpdateData(false); } //添加异步处理消息响应函数 LRESULT CServerDlg::OnSocket(WPARAM wParam, LPARAM lParam){ switch(lParam){ case FD_ACCEPT:{ SOCKADDR_IN addr; int len = sizeof(SOCKADDR_IN); socket_client = accept(socket_server, (sockaddr*)&addr, &len); if(socket_client == INVALID_SOCKET){ MessageBox("客户端套接字创建出错"); return NULL; } //获取对方的IP m_status += "客户端IP: "; m_status += inet_ntoa(addr.sin_addr); UpdateData(false); //用来显示客户端的IP地址 break; } case FD_READ:{ UpdateData(true); char buff[1024] = ""; if(!recv(socket_client, buff,1024,NULL)){ MessageBox("数据接收出错"); return NULL; } m_recv += "\r\n 客户端: "; m_recv += buff; UpdateData(false); break; } } return NULL; } void CServerDlg::OnBnClickedSendbtn() { // TODO: 在此添加控件通知处理程序代码 UpdateData(true); if(SOCKET_ERROR == send(socket_client, m_send.GetBuffer(1), m_send.GetLength(), NULL)) { MessageBox("消息发送出错"); return; } m_recv += "\r\n服务器端: "; m_recv += m_send; m_send = ""; UpdateData(false); } void CServerDlg::OnBnClickedCancel() { // TODO: 在此添加控件通知处理程序代码 if(WSACleanup()) { MessageBox("卸载Winsock dll 失败!"); return; } if(socket_server){ closesocket(socket_server); } if(socket_client){ closesocket(socket_client); } CDialog::OnCancel(); }
客户端的编写思路与服务器端类似,具体如下:
客户端:
(一)连接服务器
1.加载Winsock dll
2.准备套接字
3.连接服务器
4.设置异步套接字
(二)响应读取
(三)发送信息
void CClientDlg::OnBnClickedConnect() { // TODO: 在此添加控件通知处理程序代码 //加载WinSock dll WORD version = MAKEWORD(2,0); WSADATA wsadata; if( WSAStartup( version, &wsadata) ){ MessageBox("加载WinSock失败!"); return; } //创建套接字 socket_client = socket(AF_INET, SOCK_STREAM, NULL); if(INVALID_SOCKET == socket_client){ MessageBox("创建套接字失败!"); return; } //绑定通信地址 UpdateData(true); SOCKADDR_IN addr; memset(&addr, 0, sizeof(SOCKADDR_IN)); addr.sin_family = AF_INET; addr.sin_port = htons(80); addr.sin_addr.S_un.S_addr = inet_addr(m_ip); if(connect(socket_client, (sockaddr*)&addr, sizeof(sockaddr))){ MessageBox("尝试与服务器的连接失败!"); return; } //设置异步套接字 if( WSAAsyncSelect(socket_client, this->m_hWnd, WM_SOCKET, FD_READ)){ MessageBox("异步设置失败!"); return; } m_recv += "连接服务器成功!\r\n"; UpdateData(false); } LRESULT CClientDlg::OnSocket(WPARAM wParam , LPARAM lParam){ switch (lParam){ case FD_READ:{ UpdateData(true); char buff[1024] = ""; if(!recv(socket_client, buff , 1024, NULL)){ MessageBox("数据接收出错"); return NULL; } m_recv += "\r\n 服务器端: "; m_recv += buff; UpdateData(false); } } return NULL; } void CClientDlg::OnBnClickedSendbtn() { // TODO: 在此添加控件通知处理程序代码 UpdateData(true); if( SOCKET_ERROR == send(socket_client, m_send.GetBuffer(1), m_send.GetLength(),NULL)){ MessageBox("消息发送出错"); return; } m_recv += "\r\n 客户端: "; m_recv += m_send; m_send = ""; UpdateData(false); } void CClientDlg::OnBnClickedCancel() { // TODO: 在此添加控件通知处理程序代码 if(WSACleanup()){ MessageBox("卸载Winsock dll失败!"); return; } if(socket_client){ closesocket(socket_client); } CDialog::OnCancel(); }
相关文章推荐
- linux网络编程之用socket实现简单客户端和服务端的通信(基于UDP)
- MFC基于socket的网络聊天室的实现
- JAVA Socket应用学习——基于TCP协议实现的网络通信
- 基于TCP/IP的SOCKET接口实现网络通信
- Linux Socket 网络编程 基于GTK+ 的多线程实现的局域网通信软件
- 基于socket通信的,利用MFC实现TCP通信的C/S架构程序
- Linux Socket 网络编程 基于GTK+ 的多线程实现的局域网通信软件
- IOS网络篇7之基于第三方CocoaAsyncSocket实现Socket通信(发送图片以及类似http头信息)
- 基于WinSocket的网络通信实现
- 基于WinSocket的网络通信实现
- 如何通过socket实现网络通信
- DirectX编程:C#中利用Socket实现网络语音通信[初级版本]
- 基于WinSocket的网络通信实现
- 基于i.MX27的网络音视频通信的实现(2009-12-4)
- 利用MFC的Csocket类实现网络通信
- DirectX编程:C#中利用Socket实现网络语音通信[初级版本]
- 基于WinSocket的网络通信实现
- 基于WinSocket的网络通信实现
- 基于WinSocket的网络通信实现
- 基于WinSocket的网络通信实现