嵌入式上位机开发入门(四):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 继续带你从原理到实践,掌握嵌入式上位机开发的核心技能,敬请关注~

相关推荐
被摘下的星星18 小时前
网际协议(IP协议)
网络·tcp/ip
爱学习的小囧19 小时前
ESXi VMkernel 端口 MTU 最佳设置详解
运维·服务器·网络·php·虚拟化
寒秋花开曾相惜21 小时前
(学习笔记)4.1 Y86-64指令集体系结构(4.1.4 Y86-64异常&4.1.5 Y86-64程序)
开发语言·jvm·数据结构·笔记·学习
Theodore_102221 小时前
深度学习(15):倾斜数据集 & 精确率-召回率权衡
人工智能·笔记·深度学习·机器学习·知识图谱
不会聊天真君64721 小时前
JavaScript基础语法(Web前端开发笔记第三期)
前端·javascript·笔记
TechubNews21 小时前
Base 发布首个独立 OP Stack 框架的网络升级 Azul,将是 L2 自主迭代的开端?
大数据·网络·人工智能·区块链·能源
Fᴏʀ ʏ꯭ᴏ꯭ᴜ꯭.1 天前
Redis主从复制配置全攻略
数据库·redis·笔记
多年小白1 天前
中科院 Ouroboros 晶圆级存算一体芯片深度解析
大数据·网络·人工智能·科技·ai
发光小北1 天前
IEC104 转 Modbus TCP 网关如何应用?
网络·网络协议·tcp/ip
海绵宝宝的月光宝盒1 天前
2-非金属材料
经验分享·笔记·学习·其他·职场和发展·课程设计·制造