send()
和recv()
函数。,6. 编译并运行程序,分别启动服务器和客户端,观察是否能正常通信。,,以下是一个简单的示例代码:,,“cpp,// ServerButtonClick(),{, WSADATA wsaData;, WSAStartup(MAKEWORD(2, 2), &wsaData);,, SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);, sockaddr_in serverAddr;, serverAddr.sin_family = AF_INET;, serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");, serverAddr.sin_port = htons(8888);,, bind(serverSocket, (SOCKADDR*)&serverAddr, sizeof(SOCKADDR));, listen(serverSocket, 5);,, SOCKET clientSocket = accept(serverSocket, NULL, NULL);, char recvbuf[1024];, int ret = recv(clientSocket, recvbuf, sizeof(recvbuf), 0);, if (ret > 0), {, MessageBox(NULL, recvbuf, "Received", MB_OK);, },, closesocket(clientSocket);, closesocket(serverSocket);, WSACleanup();,},,// ClientButtonClick(),{, WSADATA wsaData;, WSAStartup(MAKEWORD(2, 2), &wsaData);,, SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);, sockaddr_in serverAddr;, serverAddr.sin_family = AF_INET;, serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");, serverAddr.sin_port = htons(8888);,, connect(clientSocket, (SOCKADDR*)&serverAddr, sizeof(SOCKADDR));, const char* sendbuf = "Hello, Server!";, send(clientSocket, sendbuf, strlen(sendbuf), 0);,, closesocket(clientSocket);, WSACleanup();,},
“,,这个示例中,服务器和客户端都在同一个对话框中,通过点击不同的按钮来启动。你可以根据需要修改代码,将其应用到实际项目中。MFC多客户端连接一个服务器跑通Windows Demo
概述
使用Microsoft Foundation Classes (MFC)和Windows套接字API,可以创建一个能够接受多个客户端连接的TCP服务器,本文将详细介绍如何实现这一功能,包括服务器和客户端的创建、代码示例以及调试方法。
准备工作
1、开发环境:
Visual Studio(推荐版本:2019或更高)
Windows操作系统
2、所需库及头文件:
afxwin.h
afxsock.h
创建服务器端
1、新建MFC应用程序
打开Visual Studio,选择“新建项目” > “MFC应用程序”。
项目名称为Server
,解决方案名称改为tcp编程
。
勾选“初始化Windows资源库”,点击完成。
2、创建服务端窗口界面
在资源视图中,打开主对话框(IDD_SERVER_DIALOG)。
添加控件:静态文本框、按钮等。
修改控件属性,使其能够显示多行文本,设置Multiline为True,Auto VScroll为True。
3、编写服务器代码
在MainDlg.h
文件中,包含必要的头文件并声明SOCKET变量。
#pragma once #include <afxwin.h> #include <afxsock.h>
在MainDlg.cpp
中,初始化套接字库并创建服务器套接字。
BEGIN_MESSAGE_MAP(CServerDlg, CDialog) // 消息映射 END_MESSAGE_MAP() CServerDlg::CServerDlg(CWnd* pParent /*=nullptr*/) : CDialog(CServerDlg:: IDD, pParent) { if (AfxSocketInit() == FALSE) { AfxMessageBox(_T("Sockets initialization failed")); } else { m_hServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (m_hServerSocket == INVALID_SOCKET) { AfxMessageBox(_T("Failed to create socket")); } else { sockaddr_in saServer; memset(&saServer, 0, sizeof(saServer)); saServer.sin_family = AF_INET; saServer.sin_addr.s_addr = htonl(INADDR_ANY); saServer.sin_port = htons(1008); // 监听端口 if (bind(m_hServerSocket, (sockaddr*)&saServer, sizeof(saServer)) == SOCKET_ERROR) { AfxMessageBox(_T("Bind failed")); } else { if (listen(m_hServerSocket, SOMAXCONN) == SOCKET_ERROR) { AfxMessageBox(_T("Listen failed")); } } } } }
4、处理客户端连接
重载OnAccept
回调函数以处理新的客户端连接请求。
void CServerDlg::OnAccept(int nErrorCode) { SOCKADDR_IN addr; memset(&addr, 0, sizeof(addr)); int addrLen = sizeof(addr); SOCKET hClientSocket = accept(m_hServerSocket, (SOCKADDR*)&addr, &addrLen); if (hClientSocket != INVALID_SOCKET) { CString strIP = inet_ntoa(addr.sin_addr); m_clientList.AddTail(hClientSocket); // 保存客户端socket m_listCtrl.InsertItem(m_listCtrl.GetItemCount(), strIP); // 更新列表控件 } CDialog::OnAccept(nErrorCode); }
5、数据交换
通过Send
和Receive
函数进行数据交换。
void CServerDlg::OnReceive(int nErrorCode) { char buffer[1024]; int nBytesReceived = recv(m_hClientSocket, buffer, sizeof(buffer), 0); if (nBytesReceived > 0) { buffer[nBytesReceived] = ' '; AfxMessageBox(buffer); // 显示接收到的数据 } CDialog::OnReceive(nErrorCode); }
创建客户端
1、新建客户端MFC应用程序
重复上述步骤,创建一个新的MFC应用程序,命名为Client
。
2、编写客户端代码
在MainDlg.h
中包含必要的头文件并声明SOCKET变量。
在MainDlg.cpp
中,初始化套接字库并创建客户端套接字。
BEGIN_MESSAGE_MAP(CClientDlg, CDialog) // 消息映射 END_MESSAGE_MAP() CClientDlg::CClientDlg(CWnd* pParent /*=nullptr*/) : CDialog(CClientDlg::IDD, pParent) { if (AfxSocketInit() == FALSE) { AfxMessageBox(_T("Sockets initialization failed")); } else { m_hClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (m_hClientSocket == INVALID_SOCKET) { AfxMessageBox(_T("Failed to create socket")); } else { hostent* pHost = gethostbyname(_T("127.0.0.1")); if (pHost == NULL) { AfxMessageBox(_T("Unable to find host")); } else { sockaddr_in saServer; memset(&saServer, 0, sizeof(saServer)); saServer.sin_family = AF_INET; saServer.sin_port = htons(1008); // 服务器端口 saServer.sin_addr.s_addr = *((u_long*)pHost>h_addr); if (connect(m_hClientSocket, (SOCKADDR*)&saServer, sizeof(saServer)) == SOCKET_ERROR) { AfxMessageBox(_T("Connect failed")); } } } } }
3、发送和接收数据
在客户端对话框中添加发送按钮和输入框,通过点击按钮发送数据。
void CClientDlg::OnBnClickedButtonSend() { UpdateData(); // 更新数据到控件变量 send(m_hClientSocket, m_strSendData, m_strSendData.GetLength(), 0); // 发送数据 }
运行与测试
1、启动服务器:运行服务器端工程,确保服务器开始监听指定端口。
2、启动客户端:分别启动多个客户端实例,连接到服务器,可以在每个客户端的消息框中看到同步显示的消息。
3、测试通信:在一个客户端中输入消息并发送,观察服务器和其他客户端是否能够同步接收到该消息。
通过上述步骤,可以实现一个简单的基于MFC的多客户端连接一个服务器的TCP通信程序,需要注意的是,实际应用中应增加更多的错误处理机制,以确保程序的健壮性和稳定性,可以考虑引入多线程技术来处理并发连接,提高服务器的性能。
原创文章,作者:未希,如若转载,请注明出处:https://www.kdun.com/ask/1217574.html