ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

网络(2)UDP通信

网络(2)UDP通信 今天学习了UDP网络编程UDP属于无连接的通信不用像TCP那样先建立连接直接发数据包就行。优点是简单、开销小缺点就是不可靠发出去的数据对方不一定能收到也没有重传机制。像直播、语音通话很多就会用UDP允许丢一点点数据优先保证速度。UDP通信UDP发送端socket 创建套接字sendto 直接把数据发给目标地址UDP接收端socket 创建套接字bind 绑定本机IP和端口recvfrom 等待接收对方发来的数据注意发送端可以不用bind操作系统会自动随机分配端口接收端必须bind固定端口别人才知道往哪个端口给你发消息。函数接口socketint socket(int domain, int type, int protocol);作用创建通信端点拿到一个文件描述符后续收发数据都靠它。domain协议族写AF_INET代表IPv4type套接字类型。SOCK_DGRAM就是UDPSOCK_STREAM是TCPprotocol一般直接填0自动匹配对应协议返回值成功返回文件描述符失败返回‑1。sendtossize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);UDP发送数据专用函数。因为UDP没有连接每次发送都要带上目标的IP和端口。sockfdsocket返回的文件描述符buf要发送的数据缓冲区len要发送多少字节flags一般填0dest_addr目标主机的地址结构体存对方IP端口addrlen地址结构体的大小返回值成功返回实际发送的字节数失败‑1。sockaddr_in结构体IPv4地址struct sockaddr_in {sa_family_t sin_family;in_port_t sin_port;struct in_addr sin_addr;};struct in_addr {uint32_t s_addr;};这个结构体用来装IP和端口。sin_family协议族填AF_INETsin_port端口号必须网络字节序sin_addr.s_addrIP地址同样是网络大端字节序编程里经常会强制转换成struct sockaddr*传给函数这是接口的固定写法。htonsuint16_t htons(uint16_t hostshort);主机字节序转网络大端字节序。我们电脑大多是小端存储网络传输统一规定用大端。设置端口的时候必须调用这个函数做转换不然端口号会错乱。inet_addrin_addr_t inet_addr(const char *cp);把字符串形式的IP比如192.168.1.100转换成网络字节序的二进制IP直接赋值给s_addr。bindint bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);把套接字和本机IP、端口绑定在一起。接收端必须bind。注意只能绑定自己本机的IP不能绑定别的机器IP同一个端口被别的程序占用bind直接失败返回值成功0失败‑1。recvfromssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);UDP接收数据。不仅拿到数据还能拿到发送方的IP和端口收到之后就知道是谁发过来的后续可以回复对方。buf存放收到数据的缓冲区len缓冲区最大能收多少字节src_addr输出参数会填充发送者的地址信息addrlen传入地址结构体大小函数内部会修改返回值成功返回收到字节数失败‑1。inet_ntoachar *inet_ntoa(struct in_addr in);和inet_addr反过来。把网络二进制IP变回我们看得懂的字符串IP打印日志的时候经常用。UDP报文头部UDP数据包头部一共8个字节源端口、目的端口、数据包长度、校验和剩下全部是应用数据。特点实现逻辑简单代码写起来比TCP少很多资源开销小传输速度快不可靠没有确认机制数据可能丢包、乱序适合对实时性要求高能接受少量丢包的场景。总结UDP无连接发送端不需要connect用sendto接收端必须bind。端口号一定要用htons转网络字节序IP用inet_addr转换。sendto每次都要指定目标地址recvfrom可以获取发送方地址。bind不能绑定别的主机IP端口被占用会绑定失败。UDP优点速度快缺点不可靠不保证数据一定到达。
返回列表