socket-Windows
通信流程
服务器
- 初始化Winsock
- 创建套接字
- 绑定套接字
- 侦听客户端的套接字
- 接收来自客户端的连接
- 接收和发送数据
- 断开连接
客户端
- 初始化Winsock
- 创建套接字
- 连接到该服务器
- 发送和接收数据
- 断开连接
Windows下使用CMake
CMake
- CMake官网下载并安装
- 无需重启,更新环境变量指令:refreshenv
make
- 安装MinGW
- 添加环境变量:bin目录添加到PATH
- bin目录中mingw-make.exe重命名为make.exe
编译指令
- cmake -G “Unix Makefiles” -DCMAKE_BUILD_TYPE=Release ..
- make
Winsock入门
1 |
|
- winsock2.h头文件包含大多数Winsock函数,结构和定义
- ws2tcpip.h头文件包含了用于处理TCP/IP网络协议的特定功能
- 对于winsock2.h需要连接到ws2_32.lib
初始化Winsock
调用Winsock函数(应用程序或DLL)的所有进程,都必须在调用Winsock函数之前初始化Windows套接字DLL,从而确保Winsock在系统上受支持。
创建名为wsaDate的WSADATA对象
1
WSADATA wsaData;
调用WSAStartup并将其值作为整数返回,并检查错误。
1
2
3
4
5
6
7
8int iResult;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
- WSAStartup函数用于初始化Winsock DLL,在调用任何Winsock函数之前,必须成功调用该函数。
- MAKEWORD(2,2)指定所需的Winsock的版本号,这里表示版本2.2
为客户端创建套接字
初始化之后,必须实例化socket对象,以供客户端使用。
声明包含sockaddr结构的addrinfo对象并初始化这些值。
1
2
3
4
5
6
7struct addrinfo *result = NULL;
struct addrinfo *ptr = NULL;
struct addrinfo hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;调用getaddrinfo函数,请求传递的服务器名称的IP地址。
1
2
3
4
5
6
7
8
9
10char *node = "baidu.com";
char *service = "http";
// Resolve the server address and port
iResult = getaddrinfo(node, service, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
return 1;
}
示例代码:
1 |
|
连接到套接字
调用connect函数,将创建的套接字和sockaddr结构作为参数传递。 检查常规错误。
1 |
|
在客户端上发送和接收数据
1 |
|
示例代码:
1 |
|
断开客户端的连接
当客户端将数据发送到服务器后,可以调用shutdown函数,指定SD_SEND关闭套接字的发送端。 这允许服务器释放此套接字的某些资源。 客户端应用程序仍可接收套接字上的数据。
1
2
3
4
5
6
7
8// shutdown the send half of the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}客户端应用程序完成接收数据后,调用closesocket函数关闭套接字,使用Windows套接字DLL完成客户端应用程序时,调用WSACleanup函数释放资源。
1
2
3
4// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
参考文档
socket-Windows
http://example.com/2025/02/22/NetworkCommunications/socket_Win/