嵌入式上位机开发入门(四):TCP 编程 ------ Client 端
目录
一、前言
大家好,这里是 Hello_Embed 。前一篇我们实现了 TCP Server 程序,本篇来创建 TCP 客户端通信。Client 端的流程会比 Server 端略微简单,详细流程可参见同系列笔记第二篇。
二、Client 端通信流程
按照 TCP 通信流程,Client 端只需四个步骤:
- open socket(socket)
- connect to server(connect)
- send and receive data(send/recv)
- close connection(close)
与 Server 端相比,Client 不需要 bind 绑定本地地址,也不需要 listen 监听,因此流程更简洁。
三、完整代码实现
cpp
#define _WIN32_WINNT 0x0600
#include<iostream>
#include<WinSock2.h>
#include<ws2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")
#define SERVER_PORT 8888
int main(int argc, char **argv)
{
WSADATA wsa;
int iSocketClient;
struct sockaddr_in tSocketServerAddr;
if(argc != 2) {
printf("Usage: %s <server_ip>\r\n", argv[0]);
return -1;
}
if(WSAStartup(MAKEWORD(2,2), &wsa) != 0) return -1;
iSocketClient = (int)socket(AF_INET, SOCK_STREAM, 0);
tSocketServerAddr.sin_family = AF_INET;
tSocketServerAddr.sin_port = htons(SERVER_PORT);
int rc = inet_pton(tSocketServerAddr.sin_family, argv[1], &tSocketServerAddr.sin_addr);
if(rc <= 0) {
printf("invalid server_ip\n");
return -1;
}
memset(tSocketServerAddr.sin_zero, 0, 8);
int iRet = connect(iSocketClient, (struct sockaddr*)&tSocketServerAddr, sizeof(tSocketServerAddr));
if(-1 == iRet) {
printf("connect error\n");
return -1;
}
while(1) {
char ucSendBuf[1024];
if(fgets((char*)ucSendBuf, sizeof(ucSendBuf), stdin)) {
int iSendLen = send(iSocketClient, (char*)ucSendBuf, (int)strlen((char*)ucSendBuf), 0);
if(iSendLen <= 0) {
printf("send error\n");
closesocket(iSocketClient);
return -1;
}
}
}
return 0;
}
四、代码解析
1. 参数检查
cpp
if(argc != 2)
{
printf("Usage: %s <server_ip>\r\n", argv[0]);
return -1;
}
argc和argv[]用于接收命令行传入的参数。argc 至少为 2(程序名 + 服务器 IP),否则打印用法提示并退出。
2. 创建 socket 并配置服务器地址
cpp
iSocketClient = (int)socket(AF_INET, SOCK_STREAM, 0);
tSocketServerAddr.sin_family = AF_INET;
tSocketServerAddr.sin_port = htons(SERVER_PORT);
int rc = inet_pton(tSocketServerAddr.sin_family, argv[1], &tSocketServerAddr.sin_addr);
socket:创建 TCP 套接字htons(SERVER_PORT):将端口号转换为网络字节序inet_pton:将点分十进制 IP 地址(如127.0.0.1)转换为网络字节序存储到结构体中
inet_pton比inet_addr更现代,能处理更多边界情况,推荐使用。
3. 连接服务器
cpp
int iRet = connect(iSocketClient, (struct sockaddr*)&tSocketServerAddr, sizeof(tSocketServerAddr));
if(-1 == iRet)
{
printf("connect error\n");
return -1;
}
connect向服务器发起连接请求。如果服务器未启动或地址错误,会返回 -1。
4. 发送数据
cpp
while(1)
{
char ucSendBuf[1024];
if(fgets((char*)ucSendBuf, sizeof(ucSendBuf), stdin))
{
int iSendLen = send(iSocketClient, (char*)ucSendBuf, (int)strlen((char*)ucSendBuf), 0);
if(iSendLen <= 0)
{
printf("send error\n");
closesocket(iSocketClient);
return -1;
}
}
}
从控制台读取数据,使用
send函数发送。如果发送失败,说明连接已断开,需关闭套接字并退出。
五、运行与测试
程序要求传入服务器 IP 作为参数:
bash
tcp_client_test.exe <server_ip>
方法一:使用 SSCOM 作为服务器
- SSCOM 设置 TCP Server,端口 8888,点击"侦听"
- 在当前文件目录打开 PowerShell
- 输入
.\tcp_client_test.exe 127.0.0.1 - 可观察到 SSCOM 下方显示"已连接"
- 在 PowerShell 发送数据,SSCOM 可正常接收

方法二:Server 与 Client 程序互连
运行 tcp_client_test.exe,然后运行前一篇的 tcp_server_test.exe,两者可实现双向通信。发送数据进行测试:

左半图为
tcp_server_test程序,右半图为tcp_client_test程序。
六、总结
- connect:Client 主动向服务器发起连接
- send:发送数据到服务器
- recv:接收服务器返回的数据
- closesocket:关闭连接
Client 端的核心是"主动连接 → 发送数据",流程简洁,只需四步即可完成通信。
七、结尾
本篇我们实现了 TCP 客户端程序,下一篇将记录 UDP 服务端的编写,打通 TCP 与 UDP 两种通信方式的完整知识体系。
Hello_Embed 继续带你从原理到实践,掌握嵌入式上位机开发的核心技能,敬请关注~