C++ socket网络编程是基于操作系统提供的套接字接口实现进程间网络通信的技术,TCP作为可靠的传输层协议,常被用于需要稳定数据传输的场景,下面我们通过实例讲解TCP客户端与服务端的完整实现过程。
TCP通信的基本流程
TCP服务端和客户端的交互遵循固定的流程,理解这个流程是实现代码的基础:
- 服务端流程:创建socket、绑定地址端口、监听连接、接受客户端连接、收发数据、关闭连接
- 客户端流程:创建socket、连接服务端、收发数据、关闭连接
服务端实现代码
服务端需要先启动,等待客户端的连接请求,以下是Windows平台下的实现代码,Linux平台仅需调整头文件和部分函数即可:
#include <iostream>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
int main() {
// 初始化套接字库
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cout << "WSAStartup failed" << std::endl;
return 1;
}
// 创建服务端socket
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET) {
std::cout << "socket create failed" << std::endl;
WSACleanup();
return 1;
}
// 设置服务端地址信息
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8888); // 端口号,可自定义
serverAddr.sin_addr.S_un.S_addr = INADDR_ANY; // 监听所有网卡
// 绑定地址和端口
if (bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
std::cout << "bind failed" << std::endl;
closesocket(serverSocket);
WSACleanup();
return 1;
}
// 开始监听,最大等待连接数为5
if (listen(serverSocket, 5) == SOCKET_ERROR) {
std::cout << "listen failed" << std::endl;
closesocket(serverSocket);
WSACleanup();
return 1;
}
std::cout << "server start, waiting for client connect..." << std::endl;
// 接受客户端连接
sockaddr_in clientAddr;
int clientAddrLen = sizeof(clientAddr);
SOCKET clientSocket = accept(serverSocket, (sockaddr*)&clientAddr, &clientAddrLen);
if (clientSocket == INVALID_SOCKET) {
std::cout << "accept failed" << std::endl;
closesocket(serverSocket);
WSACleanup();
return 1;
}
std::cout << "client connect success" << std::endl;
// 接收客户端发送的数据
char recvBuf[1024] = {0};
int recvLen = recv(clientSocket, recvBuf, sizeof(recvBuf), 0);
if (recvLen > 0) {
std::cout << "receive client data: " << recvBuf << std::endl;
// 给客户端发送响应数据
const char* sendBuf = "hello client, i receive your data";
send(clientSocket, sendBuf, strlen(sendBuf), 0);
}
// 关闭套接字,清理资源
closesocket(clientSocket);
closesocket(serverSocket);
WSACleanup();
return 0;
}
客户端实现代码
客户端需要先启动服务端,再运行才能成功连接,以下是对应客户端的实现代码:
#include <iostream>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
int main() {
// 初始化套接字库
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cout << "WSAStartup failed" << std::endl;
return 1;
}
// 创建客户端socket
SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET) {
std::cout << "socket create failed" << std::endl;
WSACleanup();
return 1;
}
// 设置要连接的服务端地址信息
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8888); // 和服务端端口一致
serverAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // 连接本地服务端
// 连接服务端
if (connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
std::cout << "connect server failed" << std::endl;
closesocket(clientSocket);
WSACleanup();
return 1;
}
std::cout << "connect server success" << std::endl;
// 给服务端发送数据
const char* sendBuf = "hello server, this is client";
send(clientSocket, sendBuf, strlen(sendBuf), 0);
// 接收服务端的响应数据
char recvBuf[1024] = {0};
int recvLen = recv(clientSocket, recvBuf, sizeof(recvBuf), 0);
if (recvLen > 0) {
std::cout << "receive server data: " << recvBuf << std::endl;
}
// 关闭套接字,清理资源
closesocket(clientSocket);
WSACleanup();
return 0;
}
代码运行注意事项
运行上述代码时需要注意以下几点:
- Windows平台下需要包含
winsock2.h头文件并链接ws2_32.lib库,Linux平台需要包含sys/socket.h、netinet/in.h、arpa/inet.h等头文件,不需要链接额外的库 - 服务端需要先启动,再运行客户端,否则客户端会连接失败
- 端口号可以自定义,只要没有被其他程序占用即可,范围建议在1024到65535之间
- 如果是在不同机器上测试,需要将客户端的
127.0.0.1替换成服务端的实际IP地址
核心函数说明
代码中用到的几个核心socket函数作用如下:
| 函数名 | 作用说明 |
|---|---|
socket() | 创建一个套接字描述符,指定地址族、套接字类型和协议类型 |
bind() | 将套接字和指定的IP地址、端口号绑定,服务端必须调用 |
listen() | 将套接字设置为监听状态,等待客户端的连接请求 |
accept() | 接受客户端的连接请求,返回一个新的套接字用于和该客户端通信 |
connect() | 客户端调用,向指定的服务端发起连接请求 |
send()/recv() | 用于数据的发送和接收,TCP是流式传输,需要注意数据的边界问题 |
以上就是C++下TCP客户端与服务端通信的完整实现,开发者可以在此基础上扩展功能,比如实现多客户端并发连接、添加数据校验、实现自定义的应用层协议等。
C++_socketTCP通信网络编程客户端服务端修改时间:2026-07-17 21:18:39