圣罩 发表于 2025-6-8 22:03:37

UDP协议

UDP协议提供的是面向无连接的服务,双方在通信之前不需要建立连接,接收到数据之后不需要进行回复。不保证数据包可以有序到达,以及不提供数据包进行分组和组装的服务。
UDP协议的报首

UDP协议的报首包含:两个字节的源端口+两个字节的目标端口+两个字节的包长度+两个字节的校验和+数据内容

[*]源端口号指的是发送数据的主机进程对应的端口号,该成员是可选的,如果不指定端口,则会填充为0。
[*]目标端口指的是接收数据的主机的进程对应的端口号
[*]包长度指的是UDP报首长度 + 数据内容长度之和,而包长度占16bit
[*]校验和是用于检测UDP用户数据包传输过程中是否出错,如果出错,则直接丢弃;源主机不想生成校验和,可以填充把校验和的16bit设置为0。
socket函数

此函数用于在本地创建套接字文件
example:udp_socket = socket(AF_INET,SOCK_DGRAM,0);
int socket(int domain, int type, int protocol);
//domain指的是要使用的协议族,协议族决定了通信地址类型,常用的是AF_INET协议族,这样就采用IPV4地址进行通信
//type指的是套接字类型,一般常用的类型有SOCK_STREAM 和 SOCK_DGRAM
//SOCK_STREAM:提供有序、可靠、双向、基于连接的字节流,也就是基于TCP协议。
//SOCK_DGRAM:提供不可靠、无连接、固定长度数据的数据报,是基于UDP协议。
//protocol指的是和套接字类型相关的协议,填0系统会自动选择最合适的
//ret:成功,则会返回对应的文件描述符,如果套接字创建失败,则返回-1bind函数

如果打算接收对方主机的数据,则需要把创建的套接字和本地地址以及端口进行绑定;此函数可以将创建的套接字和本地地址以及端口进行绑定。
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
//sockfd指的是创建成功的套接字返回的文件描述符
//addr指的是要绑定的本地地址的结构体指针,实际addr的结构体类型是和协议族有关的,结构体类型是struct sockaddr_in
//成员sin_family:指的是协议族,需要设置为AF_INET
//成员sin_port:指的是端口号,必须转换为网络字节序,调用htons()函数实现
//成员sin_addr:指的是IP地址,必须转换为网络字节序,调用inet_addr()实现
//addrlen:addr 参数所指向的地址结构的大小
//ret:成功返回0,失败返回-1htons函数

此函数可以将无符号短整型从主机字节序转换为网络字节序
uint16_t htons(uint16_t hostshort);
//hostshort:需要转换的16位无符号整数,表示主机字节序中的值
//ret:一个16位无符号整数,表示转换后的网络字节序值htonl函数

此函数可以将无符号整型从主机字节序转换为网络字节序
uint32_t htonl(uint32_t hostlong);
//hostlong:需要转换的32位无符号整数,表示主机字节序中的值
//ret:一个32位无符号整数,表示转换后的网络字节序值ntohs函数

此函数可以将无符号短整型从网络字节序转换为主机字节序
uint16_t ntohs(uint16_t netshort);
//需要转换的16位无符号整数,表示网络字节序中的值
//ret:16位无符号整数,表示转换后的主机字节序值ntohl函数

此函数可以将无符号整型从网络字节序转换为主机字节序
uint32_t ntohl(uint32_t netlong);
//需要转换的32位无符号整数,表示网络字节序中的值
//ret:32位无符号整数,表示转换后的主机字节序值inet_addr函数

此函数可以将点分十进制的 IP 地址字符串转换为网络字节序的 32 位无符号整数
in_addr_t inet_addr(const char *cp);
//cp:指向点分十进制的 IP 地址字符串
//ret:返回一个 32 位无符号整数,表示网络字节序的 IP 地址,失败返回INADDR_NONEsendto函数

此函数可以向目标主机发送数据
struct sockaddr_in server_addr;
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
//sockfd:创建的套接字描述符
//buf:指的是要发送的消息对应的缓冲区的地址
//len:发送的消息的大小,以字节为单位
//flags:发送消息的标志,一般设置为0
//dest_addr:目标主机的IP地址
//addrlen:目标主机的IP地址的大小
//ret:成功返回发送的消息的字节个数,失败返回-1recvfrom函数

此函数用于从目标主机接受发过来的数据
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
//sockfd:创建的套接字对应的文件描述符
//buf:接收的消息要存储的缓冲区的地址
//len:要接收的消息的大小,以字节为单位
//flags:接收消息的标志,一般设置为0
//src_addr:源主机的IP地址,如果不需要,可以设置为NULL
//addrlen:源主机的IP地址的大小
//ret:成功返回接受的消息的字节个数,失败返回-1inet_ntoa函数

此函数可以将一个32位的网络字节序的IP转换为点分十进制的网络IP
char *inet_ntoa(struct in_addr in);
//in:包含网络字节序的 32 位 IP 地址的结构
//ret:返回一个指向点分十进制字符串的指针getsockopt函数

此函数用于获取套接字的属性
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
//sockfd:指的是创建的套接字对应的文件描述符
//level:指的是选项对应的协议级别,一般把该参数设置为SOL_SOCKET
//optname:选项的名称,比如广播选项的名称是SO_BROADCAST
//optval:指的是要设置的选项值,要启用广播选项,则设置optval为非0值
//optlen:指的是选项值的长度
//ret:成功则返回0;失败则返回-1和错误码setsockopt函数

此函数用于设置套接字的属性
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
//sockfd:指的是创建的套接字对应的文件描述符
//level:指的是选项对应的协议级别,一般把该参数设置为SOL_SOCKET
//optname:选项的名称,比如广播选项的名称是SO_BROADCAST
//optval:指的是要设置的选项值,要启用广播选项,则设置optval为非0值
//optlen:指的是选项值的长度
//ret:成功则返回0;失败则返回-1和错误码组播

组播也属于套接字的属性选项,还是调用setsockopt()函数进行设置,不过函数参数需要修改
想要把主机IP加入到多播组中,需要使用一个名称叫做struct ip_mreqn的结构体,该结构体有3个成员,分别是多播组的IP地址、主机的IP地址、多播组接口索引。
struct ip_mreqn{
        struct in_addr imr_multiaddr;//多播组地址
        struct in_addr imr_address;//本地ip地址
        int imr_ifindex;//多播组接口的索引,设置为0表示任何接口
}gethostbyname函数

此函数用于将域名解析为IP地址
struct hostent {
    char* h_name;          // 主机的正式名称
    char** h_aliases;      // 主机的别名列表
    int h_addrtype;      // 地址类型(通常是 AF_INET 或 AF_INET6)
    int h_length;          // 地址长度(通常是 4 字节的 IPv4 地址或 16 字节的 IPv6 地址)
    char** h_addr_list;    // 地址列表(第一个地址通常是主要地址)
};
struct hostent* gethostbyname(const char* name);
//name:主机名或域名
//ret:成功返回指向 struct hostent 的指针,失败返回 NULLinet_ntoa函数

此函数可以把网络字节序的IP地址转换为字符串形式的点分十进制IP
char* inet_ntoa(struct in_addr in);
//in:一个 struct in_addr 类型的变量,表示一个网络字节序的 IPv4 地址
//ret:返回一个指向静态分配的字符串的指针,该字符串包含点分十进制格式的 IP 地址,失败返回NULL
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: UDP协议