C++中Socket通信基于TCP和UDP协议,TCP提供可靠连接,需经历创建套接字、绑定、监听、接受连接、收发数据和关闭;UDP无连接,直接通过sendto和recvfrom收发数据报。示例代码展示了Linux下TCP/UDP服务端与客户端的基本实现流程,同时指出Windows平台需初始化Winsock库,跨平台开发应注意头文件和初始化差异,并处理端口占用、错误返回及数据粘包等问题。

在C++中使用Socket进行网络通信,主要依赖操作系统提供的Socket API。Windows和Linux平台略有不同,但基本流程相似。下面分别介绍基于TCP和UDP的Socket通信实现方式,适用于C++语言环境。
TCP通信实现(面向连接)
TCP提供可靠的、双向的、基于字节流的通信,适合需要确保数据完整性的场景,如文件传输、即时通信等。
服务端实现步骤:- 调用
socket()创建套接字 - 使用
bind()绑定IP地址和端口 - 调用
listen()监听连接请求 - 通过
accept()接受客户端连接,获取通信套接字 - 使用
recv()接收数据,send()发送数据 - 通信结束后关闭套接字
- 调用
socket()创建套接字 - 使用
connect()连接指定的服务端IP和端口 - 通过
send()发送数据,recv()接收响应 - 通信完成后关闭连接
示例代码(Linux平台):
// 服务端(简化版)
立即学习“C++免费学习笔记(深入)”;
#include#include #include #include int main() { int server_fd, client_fd; struct sockaddr_in address; int addrlen = sizeof(address); char buffer[1024] = {0}; server_fd = socket(AF_INET, SOCK_STREAM, 0); address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(8080); bind(server_fd, (struct sockaddr *)&address, sizeof(address)); listen(server_fd, 3); std::cout << "等待客户端连接...\n"; client_fd = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen); read(client_fd, buffer, 1024); std::cout << "收到: " << buffer << std::endl; const char *response = "Hello from server"; send(client_fd, response, strlen(response), 0); close(client_fd); close(server_fd); return 0; }
// 客户端(简化版)
#include#include #include #include int main() { int sock = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in serv_addr; serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(8080); inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr); connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); const char *msg = "Hello Server"; send(sock, msg, strlen(msg), 0); char buffer[1024] = {0}; read(sock, buffer, 1024); std::cout << "响应: " << buffer << std::endl; close(sock); return 0; }
UDP通信实现(无连接)
UDP不建立连接,直接发送数据报,速度快但不可靠,适用于实时性要求高、可容忍少量丢包的场景,如音视频传输、DNS查询等。
服务端实现要点:- 创建UDP套接字:
socket(AF_INET, SOCK_DGRAM, 0) - 绑定地址和端口
- 使用
recvfrom()接收数据,并获取发送方地址 - 使用
sendto()向指定地址发送响应
- 创建UDP套接字
- 使用
sendto()发送数据到服务端 - 使用
recvfrom()接收返回数据
UDP服务端示例:
#include#include #include #include int main() { int sockfd; char buffer[1024]; struct sockaddr_in servaddr, cliaddr; socklen_t len = sizeof(cliaddr); sockfd = socket(AF_INET, SOCK_DGRAM, 0); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = INADDR_ANY; servaddr.sin_port = htons(8080); bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)); std::cout << "UDP服务端启动,等待消息...\n"; int n = recvfrom(sockfd, buffer, 1024, 0, (struct sockaddr *)&cliaddr, &len); buffer[n] = '\0'; std::cout << "收到: " << buffer << std::endl; const char *response = "UDP Hello"; sendto(sockfd, response, strlen(response), 0, (const struct sockaddr *)&cliaddr, len); close(sockfd); return 0; }
跨平台注意事项
Windows下使用Socket需包含Winsock2.h,并链接ws2_32.lib,且必须先调用WSAStartup()初始化环境。
例如:
#include#pragma comment(lib, "ws2_32.lib") WSADATA wsaData; WSAStartup(MAKEWORD(2,2), &wsaData); // ... 正常使用socket函数 WSACleanup();
Linux则直接使用标准头文件和系统调用。
常见问题与建议
- 确保端口未被占用,防火墙允许通信
- 处理函数返回值,检查是否出错(如
socket()返回-1) - 合理设置缓冲区大小,避免溢出
- TCP注意粘包问题,可通过长度前缀或分隔符解决
- UDP有最大报文限制(通常64KB),超长需分片










