VC++ 实现 TCP 网络通信(服务器 + 客户端)
本文将展示如何使用 VC++ 实现一个简单的 TCP 网络通信应用,包括服务器端和客户端。服务器端负责监听客户端请求并返回数据,而客户端向服务器发送请求并接收响应。
我们将使用 Windows API 中的 Winsock 库来实现网络通信。Winsock 是 Windows 平台上的网络编程接口,支持 TCP/IP 网络通信协议。
项目介绍
本项目的目标是通过使用 Winsock 编写一个简单的 TCP 服务器和客户端。服务器端监听特定的端口,等待客户端连接。客户端连接到服务器并发送请求,服务器返回响应。我们将用 send() 和 recv() 函数来发送和接收数据。
相关知识
Winsock 编程:
- WSAStartup:初始化 Winsock 库。
- socket:创建一个套接字。
- bind:绑定套接字到本地地址和端口。
- listen:使套接字处于监听状态。
- accept:接受客户端的连接。
- send 和 recv:发送和接收数据。
- closesocket:关闭套接字。
- WSACleanup:清理 Winsock。
TCP 和 UDP:
- 本项目使用的是 TCP 协议,确保数据传输可靠并按顺序到达。
代码结构
服务器端:
- 初始化 Winsock 库。
- 创建套接字并绑定到本地 IP 地址和端口。
- 监听客户端的连接请求。
- 接受客户端连接并进行数据交换。
- 关闭连接。
客户端:
- 初始化 Winsock 库。
- 创建套接字并连接到服务器。
- 发送数据到服务器并接收服务器响应。
- 关闭连接。
服务器端代码
#include <winsock2.h>
#include <iostream>
#include <string>
#pragma comment(lib, "ws2_32.lib") // 链接 Winsock 库
// 服务器端
int main() {
WSADATA wsaData;
SOCKET listenSocket, clientSocket;
sockaddr_in serverAddr, clientAddr;
int clientAddrSize = sizeof(clientAddr);
char recvBuffer[512];
// 初始化 Winsock 库
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cerr << "Winsock initialization failed." << std::endl;
return 1;
}
// 创建监听套接字
listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listenSocket == INVALID_SOCKET) {
std::cerr << "Socket creation failed." << std::endl;
WSACleanup();
return 1;
}
// 配置服务器地址
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8080); // 设置端口
serverAddr.sin_addr.s_addr = INADDR_ANY; // 监听所有接口
// 绑定套接字到地址
if (bind(listenSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
std::cerr << "Bind failed." << std::endl;
closesocket(listenSocket);
WSACleanup();
return 1;
}
// 开始监听客户端连接
if (listen(listenSocket, 1) == SOCKET_ERROR) {
std::cerr << "Listen failed." << std::endl;
closesocket(listenSocket);
WSACleanup();
return 1;
}
std::cout << "Waiting for client connection…" << std::endl;
// 接受客户端连接
clientSocket = accept(listenSocket, (struct sockaddr*)&clientAddr, &clientAddrSize);
if (clientSocket == INVALID_SOCKET) {
std::cerr << "Accept failed." << std::endl;
closesocket(listenSocket);
WSACleanup();
return 1;
}
std::cout << "Client connected!" << std::endl;
// 接收数据
int bytesReceived = recv(clientSocket, recvBuffer, sizeof(recvBuffer), 0);
if (bytesReceived > 0) {
recvBuffer[bytesReceived] = '\\0'; // 添加字符串结束符
std::cout << "Received from client: " << recvBuffer << std::endl;
// 发送响应
std::string response = "Hello from server!";
send(clientSocket, response.c_str(), response.length(), 0);
} else {
std::cerr << "Receive failed." << std::endl;
}
// 关闭套接字
closesocket(clientSocket);
closesocket(listenSocket);
WSACleanup();
return 0;
}
客户端代码
#include <winsock2.h>
#include <iostream>
#include <string>
#pragma comment(lib, "ws2_32.lib") // 链接 Winsock 库
// 客户端
int main() {
WSADATA wsaData;
SOCKET clientSocket;
sockaddr_in serverAddr;
char sendBuffer[512], recvBuffer[512];
// 初始化 Winsock 库
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cerr << "Winsock initialization failed." << std::endl;
return 1;
}
// 创建客户端套接字
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET) {
std::cerr << "Socket creation failed." << std::endl;
WSACleanup();
return 1;
}
// 设置服务器地址
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8080); // 设置端口
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器 IP 地址
// 连接到服务器
if (connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
std::cerr << "Connection failed." << std::endl;
closesocket(clientSocket);
WSACleanup();
return 1;
}
std::cout << "Connected to server!" << std::endl;
// 发送数据
std::string message = "Hello from client!";
send(clientSocket, message.c_str(), message.length(), 0);
// 接收响应
int bytesReceived = recv(clientSocket, recvBuffer, sizeof(recvBuffer), 0);
if (bytesReceived > 0) {
recvBuffer[bytesReceived] = '\\0'; // 添加字符串结束符
std::cout << "Received from server: " << recvBuffer << std::endl;
} else {
std::cerr << "Receive failed." << std::endl;
}
// 关闭套接字
closesocket(clientSocket);
WSACleanup();
return 0;
}
代码解释
服务器端代码:
客户端代码:
测试与运行
运行服务器端:
- 先运行服务器端程序,它将开始监听端口 8080。
运行客户端:
- 运行客户端程序,客户端会连接到本地服务器并发送消息。
- 服务器接收到消息后会回复客户端,客户端接收服务器的响应并显示。
示例输出
-
服务器端(假设客户端发送消息 "Hello from client!"):
Waiting for client connection…
Client connected!
Received from client: Hello from client!
客户端(收到服务器的响应 "Hello from server!"):
Connected to server!
Received from server: Hello from server!
总结
通过这个项目,我们实现了一个简单的 TCP 网络通信程序,包含服务器端和客户端。通过使用 Winsock 库的基本功能,我们能够在 C++ 中创建一个 TCP 服务器并与客户端进行通信。此代码可以作为更复杂网络应用程序的基础。
评论前必须登录!
注册