使用 Winsock 实现简单的 TCP 服务器和客户端教程

avatar
作者
筋斗云
阅读量:4

使用 Winsock 实现 TCP 服务器和客户端

在这篇博客中,我们将介绍如何使用 Winsock API 在 Windows 上实现简单的 TCP 服务器和客户端。Winsock 是 Windows 套接字扩展,提供了网络编程所需的 API。通过这两个示例代码,我们将展示如何初始化 Winsock 库、创建套接字、进行连接以及发送和接收数据。

服务器代码详解

首先,我们来看一下服务器端的实现:

#include<iostream> #include<WinSock2.h>  #pragma comment(lib,"ws2_32.lib")  using namespace std;  int main() {     // 初始化套接字库     WORD mVersion;     WSADATA wsaData;     int err;     mVersion = MAKEWORD(1, 1); // 版本 1.1     err = WSAStartup(mVersion, &wsaData);     if (err != 0)     {         return err;     }      // 检查版本     if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)     {         WSACleanup();         return -1;     }      // 创建套接字     SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);     if (sockSrv == INVALID_SOCKET)     {         WSACleanup();         return 1;     }      // 准备绑定信息     SOCKADDR_IN addrSrv;     addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);     addrSrv.sin_family = AF_INET;     addrSrv.sin_port = htons(6000);      // 绑定套接字     if (bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(addrSrv)) == SOCKET_ERROR)     {         closesocket(sockSrv);         WSACleanup();         return 1;     }      // 监听端口     if (listen(sockSrv, 10) == SOCKET_ERROR)     {         closesocket(sockSrv);         WSACleanup();         return 1;     }      cout << "Server started at port 6000" << endl;      SOCKADDR_IN addrCli;     int len = sizeof(addrCli);     char recvBuf[100];     char sendBuf[100];      while (true)     {         // 接受客户端连接         SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrCli, &len);         if (sockConn == INVALID_SOCKET)         {             continue;         }          sprintf_s(sendBuf, "Server send something");         send(sockConn, sendBuf, strlen(sendBuf) + 1, 0);         recv(sockConn, recvBuf, sizeof(recvBuf), 0);          cout << recvBuf << endl;          // 关闭客户端套接字         closesocket(sockConn);     }      // 关闭服务器套接字并清理库     closesocket(sockSrv);     WSACleanup();      system("pause");     return 0; } 

服务器代码解释

  1. 初始化 Winsock 库

    • 使用 WSAStartup 函数初始化 Winsock 库,并请求版本 1.1。
    • 检查版本是否正确初始化。
  2. 创建套接字

    • 使用 socket 函数创建一个 TCP 套接字。
  3. 绑定和监听

    • 使用 bind 函数将套接字绑定到本地地址和端口。
    • 使用 listen 函数使套接字进入监听模式,准备接收连接请求。
  4. 接受连接并处理数据

    • 使用 accept 函数等待客户端连接请求。
    • 发送和接收数据,通过 sendrecv 函数进行通信。
  5. 清理资源

    • 使用 closesocket 关闭套接字。
    • 使用 WSACleanup 清理 Winsock 库。

客户端代码详解

接下来是客户端的实现:

#include<iostream> #include<WinSock2.h>  #pragma comment(lib,"ws2_32.lib")  using namespace std;  int main() {     // 初始化套接字库     WORD mVersion;     WSADATA wsaData;     int err;     mVersion = MAKEWORD(1, 1); // 版本 1.1     err = WSAStartup(mVersion, &wsaData);     if (err != 0)     {         return err;     }      // 检查版本     if (LOBYTE(mVersion, wsaData) != 1 || HIBYTE(mVersion, wsaData) != 1)     {         WSACleanup();         return -1;     }      // 创建 TCP 套接字     SOCKET sockCli = socket(AF_INET, SOCK_STREAM, 0);     SOCKADDR_IN addrSrv;     addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");     addrSrv.sin_port = htons(6000);     addrSrv.sin_family = AF_INET;      // 连接服务器     connect(sockCli, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));      char sendBuf[] = "Cli send ...";     char recvBuf[100];      // 发送数据到服务器     send(sockCli, sendBuf, strlen(sendBuf) + 1, 0);      // 接收服务器发送的数据     recv(sockCli, recvBuf, sizeof(recvBuf), 0);      cout << recvBuf << endl;      // 关闭套接字并清理库     closesocket(sockCli);     WSACleanup();      system("pause");     return 0; } 

客户端代码解释

  1. 初始化 Winsock 库

    • 使用 WSAStartup 函数初始化 Winsock 库,并请求版本 1.1。
    • 检查版本是否正确初始化。
  2. 创建套接字

    • 使用 socket 函数创建一个 TCP 套接字。
  3. 连接服务器

    • 使用 connect 函数连接到指定 IP 地址和端口的服务器。
  4. 发送和接收数据

    • 通过 send 函数向服务器发送数据。
    • 通过 recv 函数接收服务器发送的数据。
  5. 清理资源

    • 使用 closesocket 关闭套接字。
    • 使用 WSACleanup 清理 Winsock 库。

总结

通过上述示例,我们了解了如何在 Windows 平台上使用 Winsock API 实现基本的 TCP 服务器和客户端。关键步骤包括初始化 Winsock 库、创建套接字、绑定和监听、连接服务器以及数据通信。虽然这些示例较为基础,但它们提供了构建更复杂网络应用程序的基础。希望这篇博客对你理解 Winsock 编程有所帮助。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!