C语言Windows环境Socket通信实现:Server与Client代码详解
在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语言网络编程的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













