基于 TCP 的 C/S 通信程序设计实验博客
基于 TCP 的 C/S 通信程序设计实验博客
课程:网络协议分析|组别:网安2413 第十九组
组员:许俊杰、叶海林、李想、王兴安
实验环境:Windows11、Visual Studio 2025、C++ Winsock套接字编程
本次实验我们完成基于Windows Winsock的TCP客户端‑服务器一问一答通信小程序。服务器监听5555端口,客户端连接本机回环地址127.0.0.1:5555。
客户端发送消息:我是集美大学网络空间安全专业学生
服务器收到之后回复:我也是集美大学网络空间安全专业学生。
通过本次上机实操,熟悉TCP面向连接的完整通信流程,上手Winsock常用接口,理解C/S客户端服务器通信模型。
一、实验目的
- 熟悉 Windows Socket(Winsock)API 编程流程,理解 TCP 面向连接的通信原理。
- 掌握 TCP 服务端 socket 创建、绑定端口、监听、接收连接、收发数据的过程。
- 掌握 TCP 客户端 socket 创建、发起连接、收发数据的实现方法。
- 理解客户端与服务器之间一问一答的通信模型,验证 TCP 可靠传输特性。
二、实验原理
TCP属于面向连接、可靠的传输层协议,服务器和客户端执行的程序流程并不对称。
服务端执行顺序:
socket()创建套接字 → bind()绑定IP与端口 → listen()开启监听 → accept()阻塞等待客户端连接 → recv()接收消息 → send()应答消息 → closesocket()关闭套接字 → WSACleanup()释放Winsock库资源。
客户端执行顺序:
socket()创建套接字 → connect()主动向服务器发起TCP连接 → send()发送消息 → recv()接收应答数据 → closesocket()关闭套接字 → WSACleanup()释放库资源。
这里有一个很容易踩坑的细节:recv读取到的是原始字节流,不会自动补充字符串结束符\0,需要我们手动添加,否则控制台打印会出现乱码、输出异常。
三、实验环境
- 操作系统:Windows11
- 开发工具:Visual Studio 2025
- 编程语言:C++
- 测试端口:5555,本机回环测试地址:
127.0.0.1
四、实验步骤
4.1 创建服务器Server项目
打开Visual Studio,新建空C++控制台项目,项目命名为Server。

在项目里面添加server.cpp源文件。
右键项目打开属性页面,选择链接器-输入,在附加依赖项里面填写ws2_32.lib,保存配置。

编写服务器代码,生成解决方案,确认编译没有报错。
服务器核心关键代码片段:
// 1.初始化Winsock
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
// 2.创建监听套接字
SOCKET listenSock = socket(AF_INET, SOCK_STREAM, 0);
// 3.配置地址、绑定端口
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(5555);
inet_pton(AF_INET,"127.0.0.1",&serverAddr.sin_addr);
bind(listenSock,(sockaddr*)&serverAddr,sizeof(serverAddr));
// 4.开启监听,等待客户端连接
listen(listenSock,5);
SOCKET newSock = accept(listenSock,NULL,NULL);
// 5.接收客户端消息、回复消息
char recvBuf[1024]={0};
char sendBuf[]="我也是集美大学网络空间安全专业学生";
int len=recv(newSock,recvBuf,1023,0);
recvBuf[len]='\0';
cout<<"收到客户端消息:"<<recvBuf<<endl;
send(newSock,sendBuf,strlen(sendBuf),0);
// 6.释放资源
closesocket(newSock);
closesocket(listenSock);
WSACleanup();
4.2 创建客户端 Client 项目
在解决方案上右键,添加新项目,同样选择空 C++ 控制台项目,命名 Client。添加client.cpp源文件。
注意:客户端项目也必须同样配置链接器附加依赖项ws2_32.lib,否则编译会出错。
编写客户端代码,生成解决方案,确认编译成功。

客户端关键代码片段:
// 1.初始化Winsock
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
// 2.创建客户端套接字
SOCKET clientSock = socket(AF_INET, SOCK_STREAM, 0);
// 3.填写服务器地址信息
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(5555);
inet_pton(AF_INET,"127.0.0.1",&serverAddr.sin_addr);
// 4.连接服务器
connect(clientSock,(sockaddr*)&serverAddr,sizeof(serverAddr));
// 5.发送消息,接收服务器回复
char sendBuf[]="我是集美大学网络空间安全专业学生";
char recvBuf[1024]={0};
send(clientSock,sendBuf,strlen(sendBuf),0);
int len=recv(clientSock,recvBuf,1023,0);
recvBuf[len]='\0';
cout<<"收到服务器回复:"<<recvBuf<<endl;
// 6.释放资源
closesocket(clientSock);
WSACleanup();
4.3 运行测试
⚠️ 运行顺序:先启动服务器,后启动客户端
把 Server 设置为启动项目,点击启动(不调试),服务器程序启动,进入端口监听,等待客户端接入。

不要关闭服务器的黑窗口。接着把 Client 设置为启动项目,启动客户端程序。

最终两个程序同时运行的效果如下图,服务器打印收到的客户端消息,客户端打印服务器返回的应答文字。

运行现象简单说明:
服务器启动后监听 5555 端口,等待客户端连接;客户端发起连接成功之后发送预设消息;服务器接收消息,回复应答内容,两端控制台打印完整通信内容。
五、调试过程遇到的问题记录
(1)inet_addr报 C4996 过时警告
新版 VS 编译器把inet_addr标记为废弃接口。
两种处理方案:改用新函数inet_pton;或者代码最开头添加宏定义#define _WINSOCK_DEPRECATED_NO_WARNINGS屏蔽警告。
(2)recv接收数据输出乱码、打印异常
recv拿到的是原始字节流,不会自动补字符串结束符。
解决办法:使用 recv 返回的长度 len,手动执行recvBuf[len] = '\0';。
(3)connect连接失败
大概率是运行顺序搞反,先打开了客户端;也有可能端口被其他程序占用。
解决:严格先运行服务器;端口冲突时,两端代码同步更换端口号。
(4)编译提示无法解析外部符号
忘记配置链接器依赖库。服务器、客户端两个项目都需要配置ws2_32.lib。
六、小组分工与个人实验心得
组员:许俊杰、叶海林、李想、王兴安
(1)许俊杰:负责整体方案设计,完成服务端、客户端核心代码编写,搭建 VS 项目,配置 ws2_32.lib 依赖,主导程序开发,解决代码主体逻辑问题。
心得:亲手写代码才真正体会到 C/S 模型两端流程完全不一样。服务器被动等待连接,客户端主动发起连接,运行顺序不能颠倒。Winsock 库必须初始化,使用完成后要清理,不然会产生资源泄漏。
(2)叶海林:协助代码调试,排查编译警告、端口绑定失败、字符串输出异常等 bug,测试不同运行顺序带来的问题,验证通信逻辑正确性。
心得:编译警告不可以直接忽略,本次实验函数弃用、缓冲区缺少结束符这些警告,都会直接改变程序运行效果。调试要区分编译期错误和运行时错误,一步步定位问题。
(3)李想:负责程序功能测试,多次重复运行服务端与客户端,抓取运行截图,记录实验现象,整理实验原始结果。
心得:完全一样的代码,运行顺序不同,得到的结果天差地别。实验需要多次重复测试保证现象稳定,及时截图留存现象,方便后续复盘写文档。
(4)王兴安:梳理实验原理、通信流程,撰写博客和实验报告文字部分,整理关键代码片段,规范文档格式。
心得:课本上学习的 TCP 三次握手只是纸上理论,本次实验借助 socket API 把理论落地,能够对应上每一个 API 在 TCP 协议中扮演的角色,理论结合实践才更容易吃透网络编程。
七、实验总结
本次小组实验,我们完成基于 Winsock 的 TCP 一问一答 C/S 通信小程序,实现客户端和服务器双向消息交互。
实操过程熟悉了socket、bind、listen、accept、connect、send、recv等 Winsock 核心 API,分清服务器、客户端各自的工作流程。
调试过程解决了函数弃用警告、字节流字符串处理、端口占用、库链接等多类实际问题。
TCP 是面向连接的可靠传输协议,必须成功建立连接之后,两端才可以互相传输数据。小组分工协作完成编码、调试、测试、文档整理,顺利完成本次全部实验目标。

浙公网安备 33010602011771号