ARTICLE DETAIL

资讯详情

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

Linux软件编程学习笔记(九)—— 网络(一)——UDP通信

Linux软件编程学习笔记(九)—— 网络(一)——UDP通信 一、网络相关命令1. ifconfigifconfig用于查看网络接口信息。ifconfig查看所有网卡信息ifconfig -a也可以使用命令设置网卡 IPsudo ifconfig ens33 192.168.0.125/24 up其中ens33 → 网卡名称 192.168.0.125 → IP地址 /24 → 子网掩码 up → 启用网卡二、虚拟机网络模式1. NAT模式NAT 模式下Windows 有网络虚拟机一般也可以上网Windows 使用自己的 IP 地址Ubuntu 使用虚拟的 IP 地址Ubuntu 可以主动访问网络外部设备一般不能直接访问虚拟机因此NAT 模式主要用于让 Ubuntu 能够上网。2. 桥接模式桥接模式下Windows 和 Ubuntu 都使用物理网卡Windows 和 Ubuntu 分别拥有自己的 IP 地址Ubuntu 可以访问其他设备局域网中的其他设备也可以访问 Ubuntu因此如果需要让其他设备访问 Ubuntu可以使用桥接模式。三、Ubuntu网络配置打开网络配置文件sudo vim /etc/network/interfaces设置网卡使用 DHCP 自动获取 IPauto lo iface lo inet loopback auto ens33 iface ens33 inet dhcp保存退出ESC :wq重启系统sudo shutdown -r now重启后查看 IPifconfig测试网络ping www.baidu.com如果能够收到回复说明网络基本正常。四、UDP通信UDP 是一种常见的网络通信方式。文档中的 UDP 通信主要学习socket() ↓ sendto() ↓ recvfrom()UDP 发端主要使用socket sendto recvfrom五、socket()函数原型int socket(int domain, int type, int protocol);作用创建一个用于通信的套接字。参数domain协议族。IPv4 使用AF_INETtypeSOCK_STREAM表示流式套接字对应TCPSOCK_DGRAM表示数据报套接字对应UDPSOCK_RAW表示原始套接字。protocol一般使用0表示使用默认协议。返回值成功返回新的文件描述符。失败-1例如int sockfd; sockfd socket(AF_INET, SOCK_DGRAM, 0);这里创建的是IPv4 UDP 套接字。六、IPv4地址类型网络编程中常使用struct sockaddr_in结构体主要成员struct sockaddr_in { sa_family_t sin_family; // 协议族 in_port_t sin_port; // 端口号 struct in_addr sin_addr; // IP地址 };其中sin_family → 协议族 sin_port → 端口号 sin_addr → IP地址IP 地址结构struct in_addr { uint32_t s_addr; };七、htons()函数uint16_t htons(uint16_t hostshort);作用将本地字节序转换为网络大端字节序。通常设置端口号时使用addr.sin_port htons(8888);例如8888 ↓ htons() ↓ 网络字节序八、inet_addr()函数in_addr_t inet_addr(const char *cp);作用将字符串形式的 IP 地址转换成网络大端字节序的二进制地址。例如addr.sin_addr.s_addr inet_addr(192.168.0.125);这里192.168.0.125 ↓ inet_addr() ↓ 二进制网络地址九、bind()函数int bind( int sockfd, const struct sockaddr *addr, socklen_t addrlen );作用将 IP 地址和端口号与套接字绑定。例如bind(sockfd, (struct sockaddr *)addr, sizeof(addr));需要注意① 只能绑定本机 IP不能绑定其他计算机的 IP。② 一个端口不能重复绑定如果端口已经被其他程序占用就不能再次绑定。十、sendto()函数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 → 目标地址 addrlen → 目标地址长度成功返回发送的字节数。失败-1UDP 与 TCP 的一个明显区别就是UDP 使用sendto()时需要指定目标地址。十一、recvfrom()函数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和端口 addrlen → 地址长度成功返回接收到的字节数。失败-1十二、inet_ntoa()函数char *inet_ntoa(struct in_addr in);作用将网络字节序的二进制 IP 地址转换成字符串形式的 IP 地址。例如二进制IP地址 ↓ inet_ntoa() ↓ 192.168.0.125这样就可以方便地打印发送方的 IP 地址。十三、UDP通信流程UDP 的基本流程发送端 接收端 socket() socket() ↓ ↓ sendto() ───────数据──────→ recvfrom()如果双方都需要发送和接收客户端A 客户端B socket() socket() bind() bind() ↓ ↓ sendto() ───────────────────→ recvfrom() ↑ ↓ recvfrom() ←──────────────── sendto()
返回列表