嵌入式上位机开发入门(五):UDP 编程 —— Server 端实现

嵌入式上位机开发入门(五):UDP 编程 ------ Server 端实现

目录

一、前言

大家好,这里是 Hello_Embed 。前几篇我们完成了 TCP 的服务端与客户端编程,本篇开始学习 UDP 通信。UDP 是无连接的传输协议,流程比 TCP 更简单,但需要注意收发函数的使用方式有所不同。

UDP 通信程序代码实现可以结合之前的 TCP 代码以及流程图对比学习,有助于加深理解。


二、UDP Server 通信流程

UDP Server 端只需四个步骤,比 TCP 少了 listenaccept

步骤 函数 说明
1 socket 创建套接字
2 bind 绑定 IP、Port
3 recvfrom / sendto 收发数据
4 close 关闭套接字

与 TCP 最大的区别:UDP 无需建立连接,直接收发数据,使用 recvfromsendto 替代 recvsend


三、完整代码实现

cpp 复制代码
#define _WIN32_WINNT 0x0600
#include<iostream>
#include<WinSock2.h>
#include<ws2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")
#define PORT 8888

int main()
{
    WSADATA wsa;
    int iSocketServer;
    struct sockaddr_in tSocketServerAddr;
    struct sockaddr_in tSocketClientAddr;
    int msg_cnt = 0;
    char acRecvBuf[1000];
    if(WSAStartup(MAKEWORD(2,2), &wsa) != 0) return -1;

    //第一步:创建socket
    iSocketServer = (int)socket(AF_INET, SOCK_DGRAM, 0);
    tSocketServerAddr.sin_family = AF_INET;
    tSocketServerAddr.sin_port = htons(PORT);
    tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
    memset(&tSocketServerAddr.sin_zero, 0, sizeof(tSocketServerAddr.sin_zero));

    //第二步:绑定socket
    int iRet = bind(iSocketServer, (const struct sockaddr*)&tSocketServerAddr, sizeof(struct sockaddr));
    if(-1 == iRet)
    {
        printf("bind error\n");
        return -1;
    }

    //第三步:接收数据
    while(1)
    {
        int iAddrLen = sizeof(tSocketClientAddr);
        int iRecvLen = recvfrom(iSocketServer, acRecvBuf, sizeof(acRecvBuf), 0, (struct sockaddr*)&tSocketClientAddr, &iAddrLen);
        if(iRecvLen > 0)
        {
            acRecvBuf[iRecvLen] = '\0';
            char ip[20];
            inet_ntop(AF_INET, &tSocketClientAddr.sin_addr, ip, sizeof(ip));
            printf("Get Msg From %s:%d\n", ip, acRecvBuf);

            //回复
            snprintf(acRecvBuf, 1000, "Get_Msg %d", msg_cnt++);
            iAddrLen = sizeof(tSocketClientAddr);
            sendto(iSocketServer, acRecvBuf, strlen(acRecvBuf), 0, (struct sockaddr*)&tSocketClientAddr, iAddrLen);
        }
    }

    //第四步:关闭socket
    closesocket(iSocketServer);
    return 0;
}

四、代码解析

1. 创建 UDP 套接字

cpp 复制代码
iSocketServer = (int)socket(AF_INET, SOCK_DGRAM, 0);

与 TCP 的区别:SOCK_STREAM 改为 SOCK_DGRAM,表示使用 UDP 数据报模式。

2. 绑定地址

cpp 复制代码
tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
bind(iSocketServer, (const struct sockaddr*)&tSocketServerAddr, sizeof(struct sockaddr));

INADDR_ANY 表示监听本机所有网卡的数据,绑定失败时返回 -1。

3. 接收数据(recvfrom)

cpp 复制代码
int iRecvLen = recvfrom(iSocketServer, acRecvBuf, sizeof(acRecvBuf), 0, (struct sockaddr*)&tSocketClientAddr, &iAddrLen);

recvfromrecv 的区别:recvfrom 会同时获取发送方的 IP 和端口,保存在 tSocketClientAddr 中,这是 UDP 回复数据的关键。

4. 回复数据(sendto)

cpp 复制代码
snprintf(acRecvBuf, 1000, "Get_Msg %d", msg_cnt++);
sendto(iSocketServer, acRecvBuf, strlen(acRecvBuf), 0, (struct sockaddr*)&tSocketClientAddr, iAddrLen);

sendto 需要指定目标地址,这里直接使用 recvfrom 获取到的客户端地址进行回复,实现"收到即回复"的效果。


五、运行与测试

UDP 模式下测试更简单,无需手动建立连接:

  1. 运行 udp_server_test.exe
  2. 打开 SSCOM,选择 UDP 模式 ,端口设置为 8888
  3. 直接发送数据即可,无需点击连接

依次发送 123abc 进行测试,通信正常:

UDP 不需要像 TCP 那样先建立连接,只需保持端口一致(8888)即可直接通信,这正是 UDP 无连接特性的体现。


六、总结

  • SOCK_DGRAM:创建 UDP 套接字的关键参数
  • recvfrom:接收数据的同时获取发送方地址
  • sendto:向指定地址发送数据
  • UDP 无需 listen / accept / connect,流程比 TCP 更简洁

七、结尾

本篇实现了 UDP Server 端程序,下一篇将学习 UDP 客户端编程,完成 UDP 通信的完整闭环。

Hello_Embed 继续带你从原理到实践,掌握嵌入式上位机开发的核心技能,敬请关注~

相关推荐
_Evan_Yao5 小时前
端口80之外:一个Java小白和HTTP、DNS、FTP、SSH的“隐秘”交手
网络协议·http·ssh
handler017 小时前
Linux: 基本指令知识点(2)
linux·服务器·c语言·c++·笔记·学习
南境十里·墨染春水11 小时前
C++ 笔记 thread
java·开发语言·c++·笔记·学习
南境十里·墨染春水11 小时前
C++ 笔记 高级线程同步原语与线程池实现
java·开发语言·c++·笔记·学习
lkforce11 小时前
MiniMind学习笔记(二)--model_minimind.py
笔记·python·学习·minimind·minimindconfig
三品吉他手会点灯12 小时前
STM32 VSCode 开发-C/C++的环境配置中,找不到C/C++: Edit Configurations选项
c语言·c++·vscode·stm32·单片机·嵌入式硬件·编辑器
三品吉他手会点灯12 小时前
C语言学习笔记 - 1.C概述 - 本讲内容概述
c语言·笔记·学习
嵌入式小企鹅13 小时前
国产大模型与芯片加速融合,RISC-V生态多点开花,AI编程工具迈入自动化新纪元
人工智能·学习·ai·嵌入式·算力·risc-v·半导体
CinzWS13 小时前
A53多核协同(上):核间通信与缓存一致性协议——ARM多核的“心灵感应“
arm开发·嵌入式·芯片验证·原型验证·a53
yu859395814 小时前
STM32 智能红外循迹小车(含码盘测速 + 避障)
stm32·单片机·嵌入式硬件