嵌入式上位机开发入门(四):TCP 编程 —— Client 端实现

嵌入式上位机开发入门(四):TCP 编程 ------ Client 端

目录

一、前言

大家好,这里是 Hello_Embed 。前一篇我们实现了 TCP Server 程序,本篇来创建 TCP 客户端通信。Client 端的流程会比 Server 端略微简单,详细流程可参见同系列笔记第二篇。


二、Client 端通信流程

按照 TCP 通信流程,Client 端只需四个步骤:

  1. open socket(socket)
  2. connect to server(connect)
  3. send and receive data(send/recv)
  4. 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;
}

argcargv[] 用于接收命令行传入的参数。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_ptoninet_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 作为服务器

  1. SSCOM 设置 TCP Server,端口 8888,点击"侦听"
  2. 在当前文件目录打开 PowerShell
  3. 输入 .\tcp_client_test.exe 127.0.0.1
  4. 可观察到 SSCOM 下方显示"已连接"
  5. 在 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 继续带你从原理到实践,掌握嵌入式上位机开发的核心技能,敬请关注~

相关推荐
小雨青年2 小时前
鸿蒙 HarmonyOS 6 | Video 组件网络视频播放异常排查实战
网络·音视频·harmonyos
网硕互联的小客服2 小时前
CentOS系统如何卸载桌面并以shell 字符界面启动?
运维·服务器·网络·安全
雷工笔记3 小时前
读书笔记《工程师进阶之路》
笔记·学习
Engineer邓祥浩3 小时前
JVM学习笔记(4) 第二部分 自动内存管理 第3章 垃圾收集器与分配策略
jvm·笔记·学习
LuminousCPP3 小时前
3 道结构体 + 位段高频错题全拆解(附表格详解)
经验分享·笔记·结构体·位段
一定要AK4 小时前
Java流程控制
java·开发语言·笔记
chase。4 小时前
【学习笔记】基于扩散模型的运动规划学习与适应
人工智能·笔记·学习
xiaokangzhe4 小时前
MySQL主从复制读写分离笔记
笔记·mysql·adb
电子科技圈4 小时前
Durin:Aliro标准赋能,打造无缝移动入户体验
人工智能·mcu·物联网·网络协议·智能家居·智能硬件·iot