当前位置: 首页 > news >正文

【记录】基于 C++ 和 Winsock 的简单 TCP 通信实现

在本篇博客中,我们将使用 C++ 和 Windows Socket(Winsock)API 实现一个简单的 TCP 客户端与服务器之间的通信程序。该程序支持一对一连接,客户端可以向服务器发送消息,服务器接收并回传相同的消息。

TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层协议。它广泛用于网络通信中,确保数据能够准确无误地传输。

本文实现了一个 点对点 的 TCP 通信系统,包含两个部分:

  • 服务端(Server):监听指定端口,等待客户端连接,并接收和回传数据。
  • 客户端(Client):连接到服务端,发送数据并接收回传信息。

项目使用的是 Windows 平台下的 Winsock2 API,适用于 Visual Studio 编译环境。


💡 功能说明

  • 支持一对一连接(单线程)
  • 服务端持续监听,客户端可多次发送数据
  • 消息回显功能(Echo Server):服务端将收到的消息原样返回给客户端
  • 输入 exit 可退出客户端程序

🧩 代码实现

🖥️ 服务端代码(TCP_Server.cpp)

// TCP_Server.cpp: 定义 TCP 服务端程序的入口点
//#include <iostream>
#include <WinSock2.h>
#include <windows.h>#pragma comment(lib, "ws2_32.lib")using namespace std;int main()
{// 初始化 Winsock 库WSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){cout << "WSAStartup failed!" << endl;return -1;}// 创建监听 socketSOCKET listen_socket = socket(AF_INET, SOCK_STREAM, 0);if (listen_socket == INVALID_SOCKET){cout << "Socket creation failed." << endl;WSACleanup();return -1;}// 配置本地地址信息struct sockaddr_in local = { 0 };local.sin_family = AF_INET;                  // IPv4 地址族local.sin_port = htons(8080);                // 监听端口号local.sin_addr.s_addr = inet_addr("127.0.0.1"); // 本地回环地址// 绑定 socket 到本地地址if (bind(listen_socket, (struct sockaddr*)&local, sizeof(local)) == SOCKET_ERROR){cout << "Bind failed: " << WSAGetLastError() << endl;closesocket(listen_socket);WSACleanup();return -1;}// 开始监听listen(listen_socket, 10);cout << "Server is listening on port 8080..." << endl;while (true){// 接受客户端连接SOCKET client_socket = accept(listen_socket, NULL, NULL);if (client_socket == INVALID_SOCKET){cout << "Accept failed: " << WSAGetLastError() << endl;continue;}cout << "Client connected." << endl;char buffer[1024] = { 0 };while (true){// 接收客户端数据int ret = recv(client_socket, buffer, sizeof(buffer), 0);if (ret <= 0){cout << "Client disconnected." << endl;break;}cout << "Received data: " << buffer << endl;// 将收到的数据原样返回send(client_socket, buffer, strlen(buffer), 0);}// 关闭客户端 socketclosesocket(client_socket);}// 关闭监听 socketclosesocket(listen_socket);// 清理 Winsock 资源WSACleanup();return 0;
}

📱 客户端代码(TCP_Client.cpp)

// TCP_Client.cpp: 定义 TCP 客户端程序的入口点
//#include <iostream>
#include <WinSock2.h>
#include <windows.h>#pragma comment(lib, "ws2_32.lib")using namespace std;int main()
{// 初始化 Winsock 库WSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){cout << "WSAStartup failed!" << endl;return -1;}// 创建客户端 socketSOCKET client_socket = socket(AF_INET, SOCK_STREAM, 0);if (client_socket == INVALID_SOCKET){cout << "Socket creation failed." << endl;WSACleanup();return -1;}// 设置服务器地址struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;             // IPv4 地址族server_addr.sin_port = htons(8080);           // 服务器端口号server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器 IP 地址// 连接服务器if (connect(client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR){cout << "Connect to server failed: " << WSAGetLastError() << endl;closesocket(client_socket);WSACleanup();return -1;}cout << "Connected to server at 127.0.0.1:8080" << endl;char send_buffer[1024] = { 0 };char recv_buffer[1024] = { 0 };while (true){// 输入要发送的消息cout << "Enter message to send (type 'exit' to quit): ";cin.getline(send_buffer, sizeof(send_buffer));// 发送消息到服务器int send_len = send(client_socket, send_buffer, strlen(send_buffer), 0);if (send_len == SOCKET_ERROR){cout << "Send failed: " << WSAGetLastError() << endl;break;}if (strcmp(send_buffer, "exit") == 0){cout << "Exiting..." << endl;break;}// 接收服务器响应int recv_len = recv(client_socket, recv_buffer, sizeof(recv_buffer) - 1, 0);if (recv_len <= 0){cout << "Server disconnected or error occurred." << endl;break;}recv_buffer[recv_len] = '\0'; // 确保字符串结尾cout << "Server response: " << recv_buffer << endl;}// 关闭 socket 并清理 Winsock 资源closesocket(client_socket);WSACleanup();return 0;
}

✅ 运行顺序:

  1. 先启动服务端程序:TCP_Server.exe
  2. 再启动客户端程序:TCP_Client.exe
  3. 在客户端输入任意文本,服务端会回传相同内容
  4. 输入 exit 即可退出客户端
http://www.lqws.cn/news/603937.html

相关文章:

  • 基于[coze][dify]搭建一个智能体工作流,使用第三方插件抓取热门视频数据,自动存入在线表格
  • Node.js-http模块
  • 解锁医疗AI密码:医疗人工智能专业大学四年学习路径
  • 将大仓库拆分为多个小仓库
  • URL时间戳参数深度解析:缓存破坏与前端优化的前世今生
  • Linux缓存调优指南:提升服务器性能的关键策略
  • opencv基础的图像操作
  • 图像二值化方法及 Python OpenCV 实现
  • 【分明集合】特征函数、关系与运算
  • 【1.6 漫画数据库设计实战 - 从零开始设计高性能数据库】
  • 【格与代数系统】格与哈斯图
  • Instruct-GPT中强化学习(RL)训练部分详解
  • 电机控制的一些笔记
  • uniapp选择相册
  • 【读代码】百度开源大模型:ERNIE项目解析
  • web开发,旅游景点管理系统推荐算法版本demo,基于asp.net,mvc,c#,sql server
  • 【算法】动态规划 斐波那契类型: 740. 删除并获得点数
  • [面试] 手写题-防抖,节流
  • Vue 安装使用教程
  • 小白成长之路-Mysql数据库基础(二)
  • uniapp内置蓝牙打印
  • jQuery UI 安装使用教程
  • Leetcode力扣解题记录--第49题(map)
  • 电源芯片之DCDC初探索ING
  • 数据结构:递归:组合数(Combination formula)
  • 深度学习常见的激活函数
  • 2025年7月最新英雄联盟战绩自动查询工具
  • [创业之路-458]:企业经营层 - 蓝海战略 - 重构价值曲线、整合产业要素、创造新需求
  • 技术学习_人工智能_1_神经网络是如何实现的?
  • 设计模式精讲 Day 22:模板方法模式(Template Method Pattern)