Java网络编程
1 网络基础知识
每个计算设备上都有若干个网卡,每个网卡上有(全球唯一)单独的硬件地址:MAC地址,全称是Media Access Control Address,介质访问控制地址。
1.1 IP地址
每个网卡/机器都有一个或多个IP地址,在计算机网络中,依靠IP地址来定义一台计算机的位置。IP地址有两个版本:
- IPV4:如,192.168.0.100,每段从0 - 255。
- IPV6:128bit长,分成8端,每段4个16进制数,全是0的字段可以省略,如,FE::::AAAA::00C2:0002
查询当前机器联网后的IP地址:可以用ipconfig(Windows)、ifconfig(Mac/Linux)查询
保留IP:127.0.0.1 指本机
1.2 port端口
每台计算机有 0~65535 个端口,其中 0~1023 这1024个端口,OS已经占用了,操作系统会利用这些端口做一些特殊的事情。如,80是Web服务,23是telnet。剩下的端口 1024~65535 是一般程序可以使用(谨防冲突)。
两台机器通讯就是建立在IP+Port上进行的,数据从一个IP的port出发(发送方),运输到另一个IP的port(接收方)。
在Windows、Linux、Mac上都可以通过netstat -an来查询当前机器和和其他机器同讯时的 IP 和 port。
1.3 公网和内网
网络是分层的,最外层的是公网(互联网),底下的每层都是内网(局域网),IP地址可以在每个层次的网重用。tracert查看当前机器和目标机器的访问中继。
1.4 通信协议
-
UDP: User Datagram Protocol
用户数据报协议,面向无连接的协议,它不保证可靠的数据传输。但是它的速度比较快,而且对可以在较差的网络下使用。
-
TCP: Transmission Control Protocol
传输控制协议,面向连接的协议,它可以做到两台机器的可靠的、无差错的数据传输。但是它对网络的要求比较高,网络必须持续稳定,而且还要保证速度还可以。
2 Java UDP编程
UDP是一个无连接、无状态的通讯协议,具体表现是:发送方发送消息,如果接受方刚好在目的地,则可以接受;如果接收方不在目的在,则这个消息就会丢失。发送方也无法得知消息是否发送成功。UDP的好处就是简单、节省、经济。
2.1 UDP实现
在Java里面主要靠以下这两个类来实现UDP:
- DatagramSocket:通讯数据管道,需要绑定在某个IP和Port
- DatagramPacket:集装箱,用来封装数据,上面会有一个地址标签:目的地IP+Port
![](https://img-blog.csdnimg.cn/20210601205006946.png?size_16,color_FFFFFF,t_70#pic_center)
UDPSend:
package udp;
import java.net.*;
public class UDPSend {
public static void main(String[] args) throws Exception {
/*
如果不指定端口号 则会随机绑定一个可用的端口, 如下
DatagramSocket socket = new DatagramSocket();
如果有多张网卡(多个IP地址),可以选择一个IP作为本地地址,如下
DatagramSocket socket = new DatagramSocket(3001,InetAddress.getByName("192.168.1.116"));
如果不绑定IP,由JVM内核选择的IP地址。
*/
// 在本机的3000端口定义一个数据管道
DatagramSocket socket = new DatagramSocket(3001);
String msg = "Hello, World! 111";
/* 目的地址:InetAddress.getByName("127.0.0.1")
目的端口:3000 */
DatagramPacket packet = new DatagramPacket(msg.getBytes(), msg.length(),
InetAddress.getByName("127.0.0.1"), 3000);
System.out.println("UDPSend: 我要发送消息");
// 这里的send 将会解决 UDPRecv的阻塞
socket.send(packet); // 发送信息
System.out.println("UDPSend: 我发送消息结束");
Thread.sleep(1000);
// UDPSend 将会作为接受放接受消息
byte[] buf = new byte[1024];
DatagramPacket packet2 = new DatagramPacket(buf, 1024);
System.out.println("UDPSend: 我要接受消息");
socket.receive(packet2); // 接受信息
System.out.println("UDPSend: 我接受到消息");
String str = new String(packet2.getData(), 0, packet2.getLength()) +
" from " + packet2.getAddress().getHostAddress() + ":" + packet2.getPort