|
MFC中SOCKET不使用自定义类,在对话框中直接使用
- // Server.cpp : Defines the entry point for the application.
- #include "stdafx.h"
- #include "Server.h"
- #include <afxsock.h>
- #include "ServerDlg.h"
- class CMyServerApp : public CWinApp
- {
- public:
- virtual BOOL InitInstance();
- };
- CMyServerApp theApp;
- BOOL CMyServerApp::InitInstance()
- {
- AfxSocketInit(); // Initialize the socket library
- CServerDlg dlg; // Create dialog
- m_pMainWnd = &dlg; // Set main window
- dlg.DoModal(); // Show dialog
- return FALSE; // Exit application
- }
- // CServerDlg dialog
- class CServerDlg : public CDialogEx
- {
- public:
- CServerDlg(CWnd* pParent = nullptr); // Standard constructor
- virtual BOOL OnInitDialog(); // Initialize dialog
- void OnBnClickedStart(); // Start button handler
- void OnBnClickedStop(); // Stop button handler
- DECLARE_MESSAGE_MAP()
- private:
- CSocket serverSocket; // Server socket
- BOOL isRunning; // Server running state
- };
- CServerDlg::CServerDlg(CWnd* pParent /*=nullptr*/)
- : CDialogEx(IDD_SERVER_DIALOG, pParent), isRunning(FALSE)
- {
- }
- BEGIN_MESSAGE_MAP(CServerDlg, CDialogEx)
- ON_BN_CLICKED(IDC_BUTTON_START, &CServerDlg::OnBnClickedStart)
- ON_BN_CLICKED(IDC_BUTTON_STOP, &CServerDlg::OnBnClickedStop)
- END_MESSAGE_MAP()
- BOOL CServerDlg::OnInitDialog()
- {
- CDialogEx::OnInitDialog();
- return TRUE; // Return TRUE unless you set the focus to a control
- }
- void CServerDlg::OnBnClickedStart()
- {
- if (!isRunning)
- {
- if (!serverSocket.Create(12345)) // Create listening port
- {
- AfxMessageBox(_T("无法创建服务器Socket"));
- return;
- }
- serverSocket.Listen(); // Start listening
- isRunning = TRUE;
- AfxMessageBox(_T("服务器已启动"));
- // Create a thread to accept connections
- AfxBeginThread([](LPVOID pParam) -> UINT {
- CSocket* pServerSocket = (CSocket*)pParam;
- while (true)
- {
- CSocket* pClientSocket = new CSocket;
- if (pServerSocket->Accept(*pClientSocket)) // Accept client connection
- {
- TCHAR buffer[1024];
- int nReceived = pClientSocket->Receive(buffer, sizeof(buffer) - sizeof(TCHAR)); // Receive data
- buffer[nReceived / sizeof(TCHAR)] = '\0'; // Add string terminator
- // Process the received message (convert to uppercase)
- CString responseMessage = _T("处理后的信息: ");
- for (int i = 0; i < nReceived / sizeof(TCHAR); ++i)
- {
- responseMessage += toupper(buffer[i]);
- }
- pClientSocket->Send(responseMessage, responseMessage.GetLength() * sizeof(TCHAR)); // Send processed message
- pClientSocket->Close(); // Close client socket
- delete pClientSocket; // Free memory
- }
- else
- {
- delete pClientSocket; // Free memory on failure
- }
- }
- return 0; // End thread
- }, (LPVOID)&serverSocket); // Pass server socket to thread
- }
- }
- void CServerDlg::OnBnClickedStop()
- {
- if (isRunning)
- {
- serverSocket.Close(); // Close server socket
- isRunning = FALSE;
- AfxMessageBox(_T("服务器已停止"));
- }
- }
复制代码
在上面的代码中,使用 `while` 循环的目的是为了让服务器能够持续接受客户端的连接请求。具体来说, `while (true)` 循环会一直运行,直到服务器被手动停止。这意味着服务器在启动后,会不断地等待新的客户端连接并处理这些连接。
### 具体原因如下:
1. **持续监听**:服务器需要保持监听状态,以便随时接受新的客户端连接。如果没有 `while` 循环,服务器在处理完一个连接后就会结束,无法再接受后续的连接请求。
2. **处理多个客户端**:通过循环,服务器可以在同一个线程中处理多个客户端的连接。每当有一个新的客户端连接时,服务器就会创建一个新的 `CSocket` 实例来处理该连接。
3. **避免程序退出**:如果没有循环,服务器在处理完第一个客户端的请求后就会退出,导致服务无法继续运行。
### 代码中的实现:
while (true)
{
CSocket* pClientSocket = new CSocket;
if (pServerSocket->Accept(*pClientSocket)) // Accept client connection
{
// 处理客户端请求
}
}
在这个循环中,服务器会不断调用 `Accept` 方法来接受新的客户端连接。一旦有客户端连接,服务器就会处理该连接,然后继续循环,等待下一个连接。
### 注意事项:
- 在实际应用中,为了避免无限循环导致的资源占用,通常会在某些条件下退出循环,比如接收到停止命令或信号。
- 也可以使用多线程来处理每个客户端的连接,这样可以避免在一个循环中处理多个连接导致的性能瓶颈。
希望这个解释能够帮助你理解为什么要使用 `while` 循环!
|
|