linux系统编程(十)RK3568 socket之 UDP的实现

开发环境

1、讯为RK3568开发板,下载了Ubuntu系统。

2、笔记本Windows下的VScode连接开发板。

3、网线连接开发板J13网口。

VSCode远程连接开发板 :https://blog.csdn.net/u012507643/article/details/152666866?spm=1011.2124.3001.6209

UDP收发的流程:

创建socket->bind->sendto/recvfrom

一、用到的函数

1、创建

复制代码
#include <sys/socket.h>

#include <sys/types.h>

int socket(int domain, int type, int protocol);

1)domain协议族:用到的AF_INET、AF_INET6和PF_CAN、其他。

2)type套接字:

SOCK_STREAM面向连接、双向可靠字节流TCP

SOCK_DGRAM无连接、不可靠、固定长度的数据报UDP

SOCK_RAM原始套接字,允许访问底层协议IP、ICMP、CAN

SOCK_SEQPACKET可靠、连接、固定长度通讯报

3)protocol协议类型

通常设置0【自动选择合适的协议】。

IP 转换

将带'.'或者':'的ip字符串转换成二进制数据指针:af:协议类型

就是将字符串的IP地址转换成网络字节。

复制代码
int inet_pton(int af, const char *src, void *dst);

af: AF_INET

src:"192.168.1.23"

dst: struct in_addr

将二进制数据指针ip转换成带'.'或者':'的ip字符串:af:协议类型

复制代码
char *inet_ntop(int af, cosnt void *src, char *dst, socklen_t size);

端口号转换

16位主机字节序转换成网络字节序

复制代码
uint16_t htons(uint16_t hostshort);

16位网络字节序转换成16位主机字节序

复制代码
uint16_t ntohs(uint16_t netshort);

2、绑定端口

复制代码
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

sockfd:是socket函数返回的描述符

addr指向struct sockaddr。使用sockaddr_in后用强制转换成struct sockaddr。

复制代码
struct sockaddr_in {

    sa_family_t        sin_family;//地址族

    in_port_t          sin_port;//端口号(需要用htons转换)

    struct in_addr     sin_addr;//ip地址(in_addr仅含一个32位整数s_addr)

    char               sin_zero[8];//填充字段,一帮为0

};

绑定示例:

struct sockaddr_in s;

s. sin_family = AF_INET;

s. sin_port = htons(8080);

inet_pton(AF_INET, "192.168.1.23", s. sin_addr);

bind(sockfd, (const struct sockaddr *)&s, sizeof(s));

3、收发

recvfrom和sendto这两个函数实际编程时候,看函数定义即可。

二、实际代码

复制代码
#include <stdio.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>


int main(int argc, char *argv[])
{
    int fd;
    int port = 8080;
    struct sockaddr_in s, rs;
    char tx_buf[1024] = {0};
    char rx_buf[1024] = {0};
    ssize_t rlen = 0;

    if (argc > 2)
    {
        port = atoi(argv[2]);
    }
    else
    {
        printf("参数2为端口号,未输入默认8080\n");
    }

    //SOCK_DGRAM:UDP
    fd = socket(AF_INET, SOCK_DGRAM, 0);

    /* 设置本地IP和端口 */
    rs.sin_family = AF_INET;
    rs.sin_port = htons(8081);
    inet_pton(AF_INET, "192.168.31.96", &rs.sin_addr);
    /* 这里绑定本机IP和端口 */
    bind(fd, (const struct sockaddr *)&rs, sizeof(rs));

    /* 设置远程IP和端口 */
    s.sin_family = AF_INET;
    s.sin_port = htons(port);
    if (argc > 1)
    {
        inet_pton(AF_INET, argv[1], &s.sin_addr);
    }
    else
    {
        printf("参数1为ip地址,未输入默认192.168.31.98\n");
        inet_pton(AF_INET, "192.168.31.98", &s.sin_addr);
    }

    int len = 10;
    printf("本地IP:192.168.31.96,端口:8081\r\n等待接收远程数据\r\n");
    while(1) 
    {
        len = sizeof(rs);
        rlen = recvfrom(fd, rx_buf, sizeof(rx_buf), MSG_DONTWAIT, (struct sockaddr *)&rs, (socklen_t *)&len);
        if (rlen > 0 )
        {
            sendto(fd, rx_buf, strlen(rx_buf), MSG_DONTWAIT, (const struct sockaddr *)&s, sizeof(s));
            // memset(tx_buf, 0, sizeof(tx_buf));
            printf("recv:%s,len=%d\n", rx_buf, (int)rlen);
            memset(rx_buf, 0 , sizeof(rx_buf));
        }
    }

    return 0;
}

笔记本IP:192.168.31.20:8080。开发板IP:192.168.31.96:8081程序里面bind的地址

开发板运行:

笔记本发送,开发板应答,至此udp的收发完成:

三、总结

这里只是发的话还比较简单,我加了收,需要注意:

①、收的话需要bind另外定义一个结构体,bind开发板的IP和端口号,用于接受远程的udp数据包。

②、strutct sockaddr实际我们使用struct sockaddr_in 然后再进行强制转换。注意操作方便一点。

由于本人也是刚学,写的不好,也不规范,有错误的地方望前辈指正,以免误入歧途。

相关推荐
圆周率智能 iMLite AI1 天前
嵌入式高尔夫地图如何压到单洞 100KB?离线图源的数据组织与压缩思路
mcu·边缘计算·嵌入式开发·rtos·离线地图·高尔夫·高尔夫地图
Tronlong创龙3 天前
IoTGateway可以让网关开发速度快一倍?
arm开发·嵌入式开发·硬件开发·工业控制·工业开发板
捷瑞电子工坊10 天前
STM32F4的浮点运算单元(FPU)详解:让单片机告别“软算浮点”
cortex-m4·嵌入式开发·cmsis-dsp·stm32f4·fpu·浮点运算单元·硬件浮点
@嵌入式扫地僧13 天前
ECC 编程智能体嵌入式适配实战:ESP32/RK3588 驱动开发提效 60%+ 指南
驱动开发·嵌入式开发·代码优化·ai辅助开发·编程智能体
水水不水啊13 天前
告别杂乱的调试窗口:我用 Python + WebView 写了一个现代化串口助手
python·测试工具·嵌入式·嵌入式开发·串口调试·串口助手
SL-staff20 天前
MQTT Topic权限越界排查指南:JVS-IOT中系统Topic与自定义Topic的鉴权机制与实操验证
mqtt·嵌入式开发·权限控制·物联网开发·协议分析·鉴权机制·jvs-iot
星野云联AIoT技术洞察21 天前
核心板、底板、开发板有什么区别:Rockchip 项目如何选择采购方式
开发板·嵌入式开发·rockchip·核心板·芯片选型·底板
WWJA王文举21 天前
Bootloader、App 和升级分区之间是什么关系?
stm32·freertos·嵌入式开发·在线升级
玄芯散人22 天前
【筑基·057】Git代码时光机:版本控制入门到分支管理
git·版本控制·嵌入式开发
俊基科技25 天前
喇叭贴脸1cm、音量95dB,回音照样消干净——A-29P 全解析
嵌入式开发·硬件开发·ai降噪·回声消除·拾音降噪