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 然后再进行强制转换。注意操作方便一点。

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

相关推荐
凡人叶枫21 小时前
Effective C++ 条款04:确定对象被使用前已先被初始化
java·linux·开发语言·c++·嵌入式开发
凡人叶枫2 天前
Effective C++ 条款03:尽可能使用 const
linux·开发语言·c++·嵌入式开发
俊基科技4 天前
AU-48 双麦语音处理模组详解:AEC+ENC 一体化音频方案,兼容 A-47 无缝替换
语音识别·嵌入式开发·硬件开发·ai降噪·回声消除
Dlrb121110 天前
Linux系统编程-条件变量
线程·linux系统编程·条件变量·线程同步·生产者消费者模式·绝对时间·相对时间
chipsense12 天前
变频空调能效虚标技术揭秘:压缩机电流检测的硬核解析
嵌入式开发·霍尔传感器·变频空调·电流传感器·an1v·foc控制·pfc电路
止观止13 天前
在 WSL2 上从零搭建 ARM 混合编程环境
汇编·arm开发·嵌入式开发·混合编程
十年编程老舅14 天前
读懂 MCU 启动:从上电到程序运行全链路
单片机·嵌入式硬件·mcu·嵌入式·cpu·嵌入式开发·ram
dozenyaoyida14 天前
RISC-V嵌入式开发:彻底解决“undefined reference to isatty“错误全攻略
经验分享·c·cmake·嵌入式开发·isatty·没有定义问题
Dlrb121116 天前
Linux系统编程-线程
c语言·linux系统编程·线程与进程·线程控制函数
wotaifuzao17 天前
指针和中断不是魔法:用第一性原理看穿嵌入式底层(万字解析)
stm32·嵌入式开发·内存模型·c语言指针·arm架构·中断机制·rtos内核