java为udp提供的基础套接字

java为udp提供的基础套接字UDP 是面向无连接的通讯协议 由于通讯不需要连接 所以可以实现广播发送 UDP 通讯时不需要接收方确认 属于不可靠的传输 可能会出现丢包现象 实际应用中要求程序员编程验证 UDP 适用于 DNS 视频音频等多媒体通信 广播通信 广播 多播 例如我们常用的 就是一个以 UDP 为主 TCP 为辅的通讯协议 UDP 报文格式如下 UDP 首部有 8 个字节 由 4 个字段构成 每个字段都是两个字节 源端口

大家好,我是讯享网,很高兴认识大家。



UDP是面向无连接的通讯协议,由于通讯不需要连接,所以可以实现广播发送。UDP通讯时不需要接收方确认,属于不可靠的传输,可能会出现丢包现象,实际应用中要求程序员编程验证。

UDP适用于DNS、视频音频等多媒体通信、广播通信(广播、多播)。例如我们常用的,就是一个以UDP为主,TCP为辅的通讯协议。

UDP报文格式如下:

java测试udp协议端口_java

UDP首部有8个字节,由4个字段构成,每个字段都是两个字节,

源端口:数据发送方的端口号.

目的端口:数据接收方的端口号。

长度:UDP数据报的整个长度(包括首部和数据),其最小值为8(只有首部)。

校验和:检测UDP数据报在传输中是否有错,有错则丢弃。

可以使用nc发送UDP数据包:echo hello | nc -uv 127.0.0.1 9999。

用tcpdump抓取到的数据包如下(注意先运行tcpdump,然后再执行nc命令):

说明:

源端口:0xb262,十进制的45666。

目的端口:0x270f,十进制的9999。

长度:0x000e,14个字节的报文长度。

校验和:0xfe21。

bio之单播

单播就是一对一通信。

服务器端代码如下:

讯享网

客户端代码如下:

 

客户端和服务端的代码几乎一致,只不过接收和发送数据的顺序不一致,receive和sendjava为udp提供的基础套接字都欧式阻塞方法。

bio之广播

广播:同一网段所有主机都能接收,前提是端口要开启监听。

只需要将单播的例子中客户端发送数据的IP修改为255.255.255.255即可,具体修改如下:

DatagramPacket datagramPacket = new DatagramPacket(req, req.length, new InetSocketAddress("255.255.255.255", 9999));

bio之多播(组播)

多播数据报套接字类用于发送和接收IP多播包。MulticastSocket是一种DatagramSocket,它具有加入Internet上其他多播主机的“组”的附加功能。

多播组通过D类IP地址和标准UDP端口号指定。D类IP地址在224.0.0.0和239.255.255.255的范围内。地址224.0.0.0被保留,不应使用。

可以通过首先使用所需端口创建MulticastSocket,然后调用joinGroup(InetAddress groupAddr)方法来加入多播组。

服务器端代码如下:

讯享网

客户端代码如下:

 

NIO实现单播

服务器端代码如下:

 

客户端代码如下:

 

Netty实现单播

服务器端代码如下:

 

客户端代码如下:

 

Netty实现广播

只需要将netty实现的单播的客户端代码做如下修改:

1.增加option:

.option(ChannelOption.SO_BROADCAST, true)

2.将IP地址修改为广播地址255.255.255.255:

channel.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("hello server", CharsetUtil.UTF_8), new InetSocketAddress("255.255.255.255", 8899)));

底层实现

recvfrom负责接收UDP数据,其函数声明如下:

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

sendto负责发送UDP数据,其函数声明如下:

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

下面通过对bio之单播的例子所产生的系统调用进行跟踪:

启动服务器端服务Server:

# strace -ff -o out java Server

然后使用nc命令充当客户端进行连接:echo hello | nc -uv 127.0.0.1 9999。

产生的系统调用中关键信息如下:

 

可见发送和接收数据确实使用了上面的系统调用,另外上面的系统调用中并没有listen函数,不需要监听端口,再次验证UDP是面向无连接的。

小讯
上一篇 2024-12-31 19:47
下一篇 2024-12-31 20:58

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/1050.html