MFC 提供了一套丰富的类库来简化 Windows 应用程序的网络编程。以下是使用 MFC 进行 socket 编程时服务端和客户端的基本流程:
服务端流程:
-
初始化 Winsock :
调用
AfxSocketInit
初始化 Winsock 库。 -
创建
CSocket
或CAsyncSocket
对象 :创建一个 socket 对象用于监听连接。
-
绑定地址 :
使用
Bind
方法将 socket 绑定到一个本地地址和端口。 -
监听连接 :
调用
Listen
方法开始监听进入的连接请求。 -
接受连接 :
使用
Accept
方法接受客户端的连接请求,创建一个新的 socket 用于与客户端通信。 -
数据交换 :
使用
Send
和Receive
方法与客户端进行数据交换。 -
关闭连接 :
使用
Close
方法关闭与客户端的连接。 -
清理 Winsock :
调用
WSACleanup
清理 Winsock 库。
客户端流程:
-
初始化 Winsock :
同服务端。
-
创建
CSocket
或CAsyncSocket
对象 :创建 socket 对象用于发起连接。
-
连接到服务端 :
使用
Create
方法创建 socket,并使用Connect
方法连接到服务端。 -
数据交换 :
使用
Send
和Receive
方法与服务端进行数据交换。 -
关闭连接 :
使用
Close
方法关闭连接。 -
清理 Winsock :
同服务端。
示例代码:
服务端示例:
// CServerSocket 类
class CServerSocket : public CAsyncSocket
{
public:
CServerSocket() {
if (!AfxSocketInit())
AfxThrowSocketException(WSAEINITIALIZATION_FAILED);
}
void StartServer(unsigned short nPort) {
if (!Bind((SOCKADDR_IN){AF_INET, htons(nPort), INADDR_ANY})) {
AfxThrowSocketException(WSAGetLastError());
}
if (!Listen()) {
AfxThrowSocketException(WSAGetLastError());
}
}
CAsyncSocket* Accept() {
CAsyncSocket* pSocket = AcceptEx(m_hSocket, NULL, NULL, NULL, NULL, NULL, NULL);
if (pSocket) {
pSocket->SetSockOpt(SO_UPDATE_ACCEPT_CONTEXT, &m_hSocket, sizeof(m_hSocket));
}
return pSocket;
}
};
// 在应用程序中使用
CServerSocket serverSocket;
serverSocket.StartServer(8888);
while (true) {
CAsyncSocket* clientSocket = serverSocket.Accept();
// 处理客户端连接...
}
客户端示例:
// CClientSocket 类
class CClientSocket : public CAsyncSocket
{
public:
CClientSocket() {
if (!AfxSocketInit())
AfxThrowSocketException(WSAEINITIALIZATION_FAILED);
}
void ConnectToServer(const CString& strServer, UINT nPort) {
SOCKADDR_IN sockAddr = {AF_INET, htons(nPort), inet_addr(strServer)};
if (!Create() || SOCKET_ERROR == Connect(sockAddr)) {
AfxThrowSocketException(WSAGetLastError());
}
}
};
// 在应用程序中使用
CClientSocket clientSocket;
clientSocket.ConnectToServer("127.0.0.1", 8888);
// 发送和接收数据...
clientSocket.Close();
注意事项:
- 服务端的
AcceptEx
函数是 Windows 特有的,用于高效地接受大量连接。 - 客户端示例中使用了
inet_addr
将点分十进制地址转换为网络字节顺序的整数。 - 错误处理在网络编程中非常重要,示例中省略了详细的错误处理代码。
- 确保服务器端和客户端的端口号一致,并且服务器端的IP地址正确。
MFC 的网络类库提供了对底层 Winsock API 的封装,使得网络编程变得更加简单和直观。