前言
使用C++实现TCP套接字编程
服务器端
#include <iostream>
#include <cstring>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
const int PORT = 8080;
const int BUFFER_SIZE = 1024;
int main() {
// 初始化WinSock
WSADATA wsData;
if (WSAStartup(MAKEWORD(2, 2), &wsData) != 0) {
std::cerr << "Error: Failed to initialize WinSock\n";
return 1;
}
// 创建服务器端套接字
SOCKET server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == INVALID_SOCKET) {
std::cerr << "Error: Failed to create socket\n";
WSACleanup();
return 1;
}
// 绑定地址和端口
sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(PORT);
if (bind(server_socket, reinterpret_cast<sockaddr*>(&server_addr), sizeof(server_addr)) == SOCKET_ERROR) {
std::cerr << "Error: Failed to bind\n";
closesocket(server_socket);
WSACleanup();
return 1;
}
// 开始监听
if (listen(server_socket, 5) == SOCKET_ERROR) {
std::cerr << "Error: Failed to listen\n";
closesocket(server_socket);
WSACleanup();
return 1;
}
std::cout << "Server is listening on port " << PORT << std::endl;
// 接受连接
sockaddr_in client_addr;
int client_addr_len = sizeof(client_addr);
SOCKET client_socket = accept(server_socket, reinterpret_cast<sockaddr*>(&client_addr), &client_addr_len);
if (client_socket == INVALID_SOCKET) {
std::cerr << "Error: Failed to accept connection\n";
closesocket(server_socket);
WSACleanup();
return 1;
}
std::cout << "Client connected\n";
char buffer[BUFFER_SIZE];
while (true) {
// 接收客户端消息
int bytes_received = recv(client_socket, buffer, BUFFER_SIZE, 0);
if (bytes_received == SOCKET_ERROR) {
std::cerr << "Error: Failed to receive data\n";
closesocket(client_socket);
closesocket(server_socket);
WSACleanup();
return 1;
}
else if (bytes_received == 0) {
std::cout << "Client disconnected\n";
break;
}
// 将接收到的消息转换为大写
for (int i = 0; i < bytes_received; ++i) {
buffer[i] = toupper(buffer[i]);
}
// 发送大写消息给客户端
int bytes_sent = send(client_socket, buffer, bytes_received, 0);
if (bytes_sent == SOCKET_ERROR) {
std::cerr << "Error: Failed to send data\n";
closesocket(client_socket);
closesocket(server_socket);
WSACleanup();
return 1;
}
}
// 关闭套接字
closesocket(client_socket);
closesocket(server_socket);
WSACleanup();
return 0;
}
客户端
#include <iostream>
#include <cstring>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable : 4996)
const char* SERVER_IP = "127.0.0.1";
const int PORT = 8080;
const int BUFFER_SIZE = 1024;
int main() {
// 初始化WinSock
WSADATA wsData;
if (WSAStartup(MAKEWORD(2, 2), &wsData) != 0) {
std::cerr << "Error: Failed to initialize WinSock\n";
return 1;
}
// 创建客户端套接字
SOCKET client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket == INVALID_SOCKET) {
std::cerr << "Error: Failed to create socket\n";
WSACleanup();
return 1;
}
// 设置服务器地址
sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
server_addr.sin_port = htons(PORT);
// 连接到服务器
if (connect(client_socket, reinterpret_cast<sockaddr*>(&server_addr), sizeof(server_addr)) == SOCKET_ERROR) {
std::cerr << "Error: Failed to connect to server\n";
closesocket(client_socket);
WSACleanup();
return 1;
}
std::cout << "Connected to server\n";
char message[BUFFER_SIZE];
while (true) {
// 输入消息
std::cout << "Enter message: ";
std::cin.getline(message, BUFFER_SIZE);
// 发送消息给服务器
int bytes_sent = send(client_socket, message, strlen(message), 0);
if (bytes_sent == SOCKET_ERROR) {
std::cerr << "Error: Failed to send data\n";
closesocket(client_socket);
WSACleanup();
return 1;
}
// 接收服务器的响应
char buffer[BUFFER_SIZE];
int bytes_received = recv(client_socket, buffer, BUFFER_SIZE, 0);
if (bytes_received == SOCKET_ERROR) {
std::cerr << "Error: Failed to receive data\n";
closesocket(client_socket);
WSACleanup();
return 1;
}
//buffer[bytes_received] = '\0';
std::cout << "Server response: " << buffer << std::endl;
}
// 关闭套接字
closesocket(client_socket);
WSACleanup();
return 0;
}