java.net 包中提供了两种常见的网络协议的支持:
* UDP(用户数据报协议)
* 面向无连接,数据不安全,速度快。不区分客户端与服务端。
* TCP(传输控制协议)
* 面向连接(三次握手),数据安全,速度略低。分为客户端和服务端。
* 三次握手: 客户端先向服务端发起请求, 服务端响应请求, 传输数据
UDP:
发送端:
public class Demo1_Send {
/**
* * 1.发送Send
* 创建DatagramSocket, 随机端口号
* 创建DatagramPacket, 指定数据, 长度, 地址, 端口
* 使用DatagramSocket发送DatagramPacket
* 关闭DatagramSocket
* @throws SocketException
* @throws UnknownHostException
*/
public static void main(String[] args) throws Exception {
String str = "what are you 弄啥呢?";
DatagramSocket socket = new DatagramSocket(); //创建Socket相当于创建码头
DatagramPacket packet = //创建Packet相当于集装箱
new DatagramPacket(str.getBytes(), str.getBytes().length, InetAddress.getByName("127.0.0.1"), 6666);
socket.send(packet); //发货,将数据发出去
socket.close(); //关闭码头
}
}
接受端:
public class Demo1_Receive {
/**
** 2.接收Receive
* 创建DatagramSocket, 指定端口号
* 创建DatagramPacket, 指定数组, 长度
* 使用DatagramSocket接收DatagramPacket
* 关闭DatagramSocket
* 从DatagramPacket中获取数据
* @throws Exception
*/
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(6666); //创建Socket相当于创建码头
DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);//创建Packet相当于创建集装箱
socket.receive(packet); //接货,接收数据
byte[] arr = packet.getData(); //获取数据
int len = packet.getLength(); //获取有效的字节个数
System.out.println(new String(arr,0,len));
socket.close();
}
}
测试的时候可以打开对应的bin路径,然后shift+鼠标右键
执行接收端代码,但是还未执行发送端代码,此时接收端无数据显示
执行服务发送端代码,接收端显示了发送端发送的数据。
TCP:
客户端:
/**
* * 1.客户端
* 创建Socket连接服务端(指定ip地址,端口号)通过ip地址找对应的服务器
* 调用Socket的getInputStream()和getOutputStream()方法获取和服务端相连的IO流
* 输入流可以读取服务端输出流写出的数据
* 输出流可以写出数据到服务端的输入流
*/
public class Demo01_Client {
public static void main(String[] args) throws Exception {
/*
* 服务端,端口号为12345的ServerSocket必须存在,
* 否则会报错Connection refused: connect
*/
Socket socket = new Socket("127.0.0.1",12345);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
//向服务端写入数据
out.write("访问服务端".getBytes());
//获取服务端返回的数据
byte[] arr = new byte[1024];
int len = in.read(arr);
System.out.println("客户端接收到了服务端返回的数据"+new String(arr,0,len));
socket.close();
}
}
服务端:
服务端启动后 Socket socket = server.accept();该处如果没有接受到一个客户端的请求,则代码不会往下执行,可以用debug断点调试,也可以打开两个dos窗口观察。
/**
* * 2.服务端
* 创建ServerSocket(需要指定端口号)
* 调用ServerSocket的accept()方法接收一个客户端请求,得到一个Socket
* 调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的IO流
* 输入流可以读取客户端输出流写出的数据
* 输出流可以写出数据到客户端的输入流
*/
public class Demo01_Server {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(12345);
Socket socket = server.accept();
//该处打印在启动服务端的时候不会执行,直到有客户端访问server.accept()
//Socket socket = server.accept();接受到客户端请求后,代码才会往下执行
System.out.println("有客户端访问");
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
byte[] arr = new byte[1024];
int len = in.read(arr);
System.out.println(new String(arr, 0, len));
//向客户端写数据
out.write("服务端已经接受到请求了".getBytes());
server.close();
}
}