C语言Windows环境Socket通信实现:Server与Client代码详解

沿途有光
沿途有光
发布时间:2026-10-14 | 2人浏览过
原创

在Windows环境中使用C语言开发网络通信应用,核心在于调用操作系统提供的Socket API。本文将分别演示如何编写一个能够持续监听并接受连接的Server(服务器)程序,以及一个能主动发起连接并与服务器交互的Client(客户端)程序。

环境准备与基础配置

在Windows下进行C语言的Socket编程,必须引入 winsock2.h 头文件,并链接对应的库文件 ws2_32.lib。若未正确链接该库,编译时将报错。此外,在使用Winsock函数前,需通过 WSAStartup 初始化底层服务,使用完毕后通过 WSACleanup 卸载资源。

服务端(Server)实现步骤

服务端的主要职责是创建套接字、绑定端口、监听连接请求以及处理来自客户端的数据。为了便于理解,初始版本仅支持单连接处理。

第1步:初始化与绑定

首先初始化 Winsock 2.2 版本,创建一个 TCP 流式套接字,并将其绑定到本地 IP 和指定端口(如 9000),随后进入监听状态。

#include <stdio.h>
#include <winsock2.h>
#pragma comment (lib, "ws2_32")

int main()
{
    WSADATA wsaData;
    // 初始化Winsock
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    // 创建TCP套接字
    SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    sockaddr_in sockaddr;
    sockaddr.sin_family = PF_INET;
    sockaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // 绑定本地IP
    sockaddr.sin_port = htons(9000); // 监听端口

    bind(s, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR));
    listen(s, 1); // 启动监听,积压队列长度为1

    printf("listening on port [%d].\n", 9000);

    while(TRUE)
    {
        SOCKADDR clientAddr;
        int size = sizeof(SOCKADDR);
        SOCKET clientsocket;

        // 阻塞等待客户端连接
        clientsocket = accept(s, &clientAddr, &size);
        printf("***SYS*** New client touched.\n");

        // 发送欢迎消息
        char* msg = "Hello, my client.\r\n";
        send(clientsocket, msg, strlen(msg)+sizeof(char), NULL);
        printf("***SYS*** HELLO.\n");

        // 循环接收数据
        while(TRUE)
        {
            char buffer[MAXBYTE] = {0};
            recv(clientsocket, buffer, MAXBYTE, NULL);
            printf("***Client*** %s\n", buffer);
        }
        closesocket(clientsocket);
    }

    closesocket(s);
    WSACleanup();
    getchar();
    exit(0);
}

第2步:处理连接与数据收发

当有新连接时,accept 函数会返回一个新的套接字用于与该特定客户端通信。代码中展示了简单的发送(send)和接收(recv)逻辑。需注意,send 的长度参数应包含字符串结束符的大小,以确保数据的完整性。由于当前结构不支持多线程,同一时间只能处理一个客户端的连接请求。

客户端(Client)实现步骤

客户端负责连接服务端,并在成功后进行数据交换。为了调试方便,代码中加入了短暂延时。

第1步:连接与通信

客户端同样需要初始化 Winsock 并创建套接字,然后使用 connect 函数尝试连接到服务端的 IP 和端口。

#include <stdio.h>
#include <winsock2.h>
#include <Windows.h>
#pragma comment (lib, "ws2_32")

int main()
{
    Sleep(2000); // 等待2秒再连接,确保服务端已启动

    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    sockaddr_in sockaddr;
    sockaddr.sin_family = PF_INET;
    sockaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    sockaddr.sin_port = htons(9000);

    connect(s, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR));

    // 接收服务端消息
    char buffer[MAXBYTE] = {0};
    recv(s, buffer, MAXBYTE, NULL);
    printf("***SERVER***%s", buffer);

    // 循环发送消息给服务端
    while(TRUE)
    {
        char* mymsg = new char[100000];
        printf("You can chat with server now:\n");
        gets(mymsg);
        send(s, mymsg, strlen(mymsg)+sizeof(char), NULL);
    }

    closesocket(s);
    WSACleanup();
    getchar();
    exit(0);
}

开发注意事项

  • 缓冲区处理: Socket 通信涉及底层的缓冲机制,注意字符串结束符 '\0' 的处理对数据传输准确性的影响。
  • 长度参数: 在 recv 中可以使用固定缓冲区长度,但在 send 中必须根据实际发送内容的长度动态计算,以免截断或溢出。
  • 扩展建议: 上述示例为同步阻塞模型,适用于理解基础原理。在实际生产环境中,建议使用多线程、IOCP(完成端口)或异步非阻塞方式以支持高并发连接。

以上就是C语言Windows环境下Socket通信实现的详细内容,更多关于C语言网络编程的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表