一、TCP通信流程回顾
1. 服务器端流程
1. 创建Socket → socket()
2. 绑定地址和端口 → bind()
3. 开始监听 → listen()
4. 接受客户端连接 → accept()
5. 接收/发送数据 → recv()/send()
6. 关闭连接 → closesocket()
2. 客户端流程
1. 创建Socket → socket()
2. 连接服务器 → connect()
3. 发送/接收数据 → send()/recv()
4. 关闭连接 → closesocket()
二、实现TCP服务器(Echo示例)
1. 完整代码
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
#include <ctype.h>
#include <limits.h>
int main() {
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cerr << "WSAStartup failed!" << std::endl;
return 1;
}
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET) {
std::cerr << "Socket creation failed: " << WSAGetLastError() << std::endl;
WSACleanup();
return 1;
}
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
inet_pton(AF_INET,"127.0.0.1", &(serverAddr.sin_addr.s_addr));
serverAddr.sin_port = htons(8080);
if (bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
std::cerr << "Bind failed: " << WSAGetLastError() << std::endl;
closesocket(serverSocket);
WSACleanup();
return 1;
}
if (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR) {
std::cerr << "Listen failed: " << WSAGetLastError() << std::endl;
closesocket(serverSocket);
WSACleanup();
return 1;
}
std::cout << "Server started. Listening on 127.0.0.1:8080..." << std::endl;
sockaddr_in clientAddr;
int clientAddrLen = sizeof(clientAddr);
SOCKET clientSocket = accept(serverSocket, (sockaddr*)&clientAddr, &clientAddrLen);
if (clientSocket == INVALID_SOCKET) {
std::cerr << "Accept failed: " << WSAGetLastError() << std::endl;
closesocket(serverSocket);
WSACleanup();
return 1;
}
char buffer[1024];
int bytesReceived;
do {
bytesReceived = recv(clientSocket, buffer, sizeof(buffer), 0);
if (bytesReceived > 0) {
send(clientSocket, buffer, bytesReceived, 0);
std::cout << "Echoed " << bytesReceived << " bytes. Datas:" << std::string(buffer, bytesReceived) << std::endl;
}
} while (bytesReceived > 0);
closesocket(clientSocket);
closesocket(serverSocket);
WSACleanup();
return 0;
}
三、实现TCP客户端
1. 完整代码
#include <iostream>
#include <string>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
int main() {
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cerr << "WSAStartup failed!" << std::endl;
return 1;
}
SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET) {
std::cerr << "Socket creation failed: " << WSAGetLastError() << std::endl;
WSACleanup();
return 1;
}
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &(serverAddr.sin_addr.s_addr));
serverAddr.sin_port = htons(8080);
if (connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
std::cerr << "Connect failed: " << WSAGetLastError() << std::endl;
closesocket(clientSocket);
WSACleanup();
return 1;
}
std::cout << "Connected to server. Enter messages to send (type 'exit' to quit):" << std::endl;
std::string message;
char buffer[1024];
do {
std::getline(std::cin, message);
if (message == "exit") break;
send(clientSocket, message.c_str(), message.size(), 0);
int bytesReceived = recv(clientSocket, buffer, sizeof(buffer), 0);
if (bytesReceived > 0) {
std::cout << "Server echoed: " << std::string(buffer, bytesReceived) << std::endl;
}
} while (true);
closesocket(clientSocket);
WSACleanup();
return 0;
}
四、关键代码解析
1. socket()
参数说明
AF_INET
:IPv4地址族。SOCK_STREAM
:面向流的传输协议(TCP)。IPPROTO_TCP
:明确指定TCP协议(可填0自动选择)。
2. bind() 的地址设置
- INADDR_ANY:若服务器需要监听所有网卡,可改为:
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
3. listen()
的待处理队列
SOMAXCONN
:系统允许的最大挂起连接数(Windows默认为200)。
4. accept()
的阻塞特性
- 若无客户端连接,accept()会一直阻塞,直到新连接到达。
五、运行与测试
1. 客户端输入/输出

2. 服务器端输出
