实际 windows 下 socket 编程和 linux 下几乎没有什么区别,函数名、结构体信息等都一模一样的,因为这些并非是操作系统所设计决定的。而是由公共的组织在维护和约定这些规范。在 windows 下唯一与 linux 不同的就是需要自己手动加载套接字库。其他几乎完全一致,参考以下代码。
TCP 程序服务端/客户端代码
代码语言:javascript复制#include <Winsock2.h>
#include
using namespace std;
#pragma comment(lib,”Ws2_32.lib”)
int main(int argc, char* argv[])
{
WSADATA wsaData;
WORD wVersion = MAKEWORD(2, 2);
// 加载socket库
int wsaResult = WSAStartup(wVersion, &wsaData);
if (wsaResult != 0)
{
return -1;
}
// 判断加载的库是否是正确的版本
if (LOBYTE(wsaData.wVersion) != 2
HIBYTE(wsaData.wVersion) != 2)
{
WSACleanup();
return -2;
}
// 创建 socket 连接
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in srvaddr;
srvaddr.sin_family = AF_INET;
srvaddr.sin_addr.S_un.S_addr = htonl(ADDR_ANY);
srvaddr.sin_port = htons(8000);
// 绑定服务器的IP和端口
bind(sock, (sockaddr*)&srvaddr, sizeof(srvaddr));
// 监听
listen(sock, 20);
sockaddr_in cntaddr;
int len = sizeof(cntaddr);
char recvBuf[512];
while (1)
{
// 等待客户端连接
SOCKET conn = accept(sock, (sockaddr*)&cntaddr, &len);
// 有链接后接收数据
int ret = recv(conn, recvBuf, sizeof(recvBuf), 0);
cout << "recv data : " << ret << recvBuf << endl;
}
// 关闭 socket
closesocket(sock);
WSACleanup();
return 0;
}
客户端代码
#include <WinSock2.h>
#include <Ws2tcpip.h>
#include
using namespace std;
#pragma comment(lib,”Ws2_32.lib”)
int main(int argc, char* argv[])
{
// 加载套接字库
WSADATA wsaData;
WORD wVersion = MAKEWORD(2, 2);
int wsaResult = WSAStartup(wVersion, &wsaData);
if (wsaResult != 0)
{
return -1;
}
// 判断加载的库版本是否正确
if (LOBYTE(wsaData.wVersion) != 2
HIBYTE(wsaData.wVersion) != 2)
{
WSACleanup();
return -2;
}
// 创建 socket
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
// 构建服务端信息并连接
sockaddr_in srvaddr;
srvaddr.sin_family = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &(srvaddr.sin_addr));
srvaddr.sin_port = htons(8000);
connect(sock, (sockaddr*)&srvaddr, sizeof(srvaddr));
// 向服务端发送数据
char sendBuf[] = "Windows Socket 通信测试程序";
send(sock, sendBuf, sizeof(sendBuf), 0);
// 关闭套接字
closesocket(sock);
// 销毁套接字库
WSACleanup();
return 0;
}
创建 win32 控制台应用程序的空项目,将以上代码复制到你的 cpp 中就可以直接编译运行了,代码中客户端会连接服务端发送一句 “Windows Socket 通信测试程序”。
UDP 程序服务端/客户端代码
代码语言:javascript复制#include <WinSock2.h>
#include <Ws2tcpip.h>
#include <iostream>
using namespace std;
#pragma comment(lib,"Ws2_32.lib")
int main(int argc, char* argv[])
{
// 加载套接字库
WORD wVersion = MAKEWORD(2, 2);
WSAData wsData;
WSAStartup(wVersion, &wsData);
// 创建套接字
SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
// 绑定本地IP和端口
sockaddr_in srvaddr;
srvaddr.sin_family = AF_INET;
srvaddr.sin_addr.S_un.S_addr = htonl(ADDR_ANY);
srvaddr.sin_port = htons(8000);
bind(sock, (sockaddr*)&srvaddr, sizeof(srvaddr));
// 预分配各种内存,然后循环接收客户端数据
sockaddr_in cntaddr;
int len = sizeof(cntaddr);
char recvBuf[1024];
char szAddress[16];
while (1)
{
// 接收数据并把客户端信息存放到 cntaddr 结构体中
recvfrom(sock, recvBuf, sizeof(recvBuf), 0, (sockaddr*)&cntaddr, &len);
// 将结构体中的IP信息转换存放到char数组中
inet_ntop(AF_INET, &(cntaddr.sin_addr.S_un.S_addr), szAddress, sizeof(szAddress));
// 打印客户端ip和发送过来的消息
cout << szAddress << " : " << recvBuf << endl;
}
// 关闭套接字
closesocket(sock);
// 卸载套接字库
WSACleanup();
return 0;
}
客户端代码
#include <WinSock2.h>
#include <Ws2tcpip.h>
#include
using namespace std;
#pragma comment(lib,”Ws2_32.lib”)
int main(int argc, char* argv[])
{
// 加载套接字库
WORD wVersion = MAKEWORD(2, 2);
WSAData wsData;
WSAStartup(wVersion, &wsData);
// 创建套接字
SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
// 构建服务器信息直接向服务器发送数据,不像TCP无需connect
sockaddr_in srvaddr;
srvaddr.sin_family = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &(srvaddr.sin_addr.S_un.S_addr));
srvaddr.sin_port = htons(8000);
char sendBuf[] = "hello server";
sendto(sock, sendBuf, sizeof(sendBuf), 0, (sockaddr*)&srvaddr, sizeof(srvaddr));
// 关闭套接字
closesocket(sock);
// 卸载套接字库
WSACleanup();
return 0;
}
同样适用 win32 控制台应用程序空项目编译即可运行。