Java 中的网络支持:

  • InetAddress:用于表示网络上的硬件资源,即 IP 地址;
  • URL:统一资源定位符;
  • Sockets:使用 TCP 协议实现网络通信;
  • Datagram:使用 UDP 协议实现网络通信。

InetAddress

没有公有的构造函数,只能通过静态方法来创建实例。

  1. InetAddress.getByName(String host);
  2. InetAddress.getByAddress(byte[] address);
  1. public class NetDemo {
  2. public static void main(String[] args) throws UnknownHostException {
  3. // public static InetAddress getByName(String host)
  4. InetAddress address = InetAddress.getByName("LAPTOP-D9966H06");
  5. //InetAddress address = InetAddress.getByName("223.3.108.211");
  6. //InetAddress address = InetAddress.getByName("192.168.2.1");
  7. // 获取两个东西:主机名,IP地址
  8. // public String getHostName()
  9. String name = address.getHostName();
  10. // public String getHostAddress()
  11. String ip = address.getHostAddress();
  12. System.out.println(name + "---" + ip);
  13. }
  14. }

URL

可以直接从 URL 中读取字节流数据。

  1. public static void main(String[] args) throws IOException {
  2. URL url = new URL("http://www.baidu.com");
  3. /* 字节流 */
  4. InputStream is = url.openStream();
  5. /* 字符流 */
  6. InputStreamReader isr = new InputStreamReader(is, "utf-8");
  7. /* 提供缓存功能 */
  8. BufferedReader br = new BufferedReader(isr);
  9. String line;
  10. while ((line = br.readLine()) != null) {
  11. System.out.println(line);
  12. }
  13. br.close();
  14. }

Sockets

  • ServerSocket:服务器端类
  • Socket:客户端类
  • 服务器和客户端通过 InputStream 和 OutputStream 进行输入输出。

六、网络操作 - 图1

Datagram

  • DatagramSocket:通信类
  • DatagramPacket:数据包类

UDP协议

通信规则

  1. 将数据源和目的封装成数据包中,不需要建立连接;
  2. 每个数据报的大小在限制在64k;
  3. 因无连接,是不可靠协议;
  4. 不需要建立连接,速度快

UDP协议发送数据

  1. 创建发送端Socket对象
  2. 创建数据,并把数据打包
  3. 调用Socket对象的发送方法发送数据包
  4. 释放资源
  1. public class SendDemo {
  2. public static void main(String[] args) throws IOException {
  3. //1. 创建发送端Socket对象
  4. DatagramSocket ds=new DatagramSocket();
  5. //2. 创建数据,并把数据打包
  6. byte[] bys="hello".getBytes();
  7. // 长度
  8. int length = bys.length;
  9. // IP地址对象
  10. InetAddress address = InetAddress.getByName("LAPTOP-D9966H06");
  11. // 端口
  12. int port = 10086;
  13. DatagramPacket dp = new DatagramPacket(bys, length, address, port);
  14. //3. 调用Socket对象的发送方法发送数据包
  15. ds.send(dp);
  16. //4. 释放资源
  17. ds.close();
  18. }
  19. }

UDP协议接收数据

  1. 创建接收端Socket对象
  2. 创建一个数据包(接收容器)
  3. 调用Socket对象的接收方法接收数据
  4. 解析数据包,并显示在控制台
  5. 释放资源
  1. public class ReceiveDemo {
  2. public static void main(String[] args) throws IOException {
  3. //1. 创建接收端Socket对象
  4. DatagramSocket ds=new DatagramSocket(10086);
  5. //2. 创建一个数据包(接收容器)
  6. byte[] bys=new byte[1024];
  7. int length=bys.length;
  8. DatagramPacket dp=new DatagramPacket(bys,length);
  9. //3. 调用Socket对象的接收方法接收数据
  10. //public void receive(DatagramPacket p)
  11. ds.receive(dp);//阻塞式
  12. //4. 解析数据包,并显示在控制台
  13. InetAddress inetAddress=dp.getAddress();
  14. String ip=inetAddress.getHostAddress();
  15. // public byte[] getData():获取数据缓冲区
  16. // public int getLength():获取数据的实际长度
  17. byte[] bys2 = dp.getData();
  18. int len = dp.getLength();
  19. String s = new String(bys2, 0, len);
  20. System.out.println(ip + "传递的数据是:" + s);
  21. //5. 释放资源
  22. ds.close();
  23. }
  24. }

使用UDP传输键盘录入的数据

  • 接收端:
  1. public class ReceiveDemo2 {
  2. public static void main(String[] args) throws IOException {
  3. DatagramSocket ds=new DatagramSocket(12345);
  4. while (true){
  5. byte[] bys=new byte[1024];
  6. DatagramPacket dp=new DatagramPacket(bys,bys.length);
  7. ds.receive(dp);
  8. //阻塞式
  9. String ip=dp.getAddress().getHostAddress();
  10. String s = new String(dp.getData(), 0, dp.getLength());
  11. System.out.println(ip + "传递的数据是:" + s);
  12. }
  13. //接收端应该一直开着等待接收数据,不需要释放资源
  14. //ds.close();
  15. }
  16. }
  • 发送端:
  1. public class SendDemo2 {
  2. public static void main(String[] args) throws IOException {
  3. DatagramSocket ds=new DatagramSocket();
  4. //封装键盘录入数据
  5. BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
  6. String line=null;
  7. while(true){
  8. line=br.readLine();
  9. if("-1".equals(line)){
  10. break;
  11. }
  12. byte[] bys=line.getBytes();
  13. DatagramPacket dp=
  14. new DatagramPacket(bys,bys.length,InetAddress.getByName("LAPTOP-D9966H06"),12345);
  15. ds.send(dp);
  16. }
  17. br.close();
  18. //4. 释放资源
  19. ds.close();
  20. }
  21. }

TCP协议

通信规则

  1. 建立连接,形成传输数据的通道;
  2. 在连接中进行大数据量传输;
  3. 通过三次握手完成连接,是可靠协议;

4.必须建立连接,效率会稍低

TCP协议发送数据

  1. 创建发送端的Socket对象:这一步如果成功,就说明连接已经建立成功了。
  2. 获取输出流,写数据
  3. 释放资源
  1. public class ClientDemo {
  2. public static void main(String[] args) throws IOException {
  3. //1. 创建发送端的Socket对象:这一步如果成功,就说明连接已经建立成功了。
  4. Socket socket=new Socket("LAPTOP-D9966H06",8888);
  5. //2. 获取输出流,写数据
  6. OutputStream outputStream=socket.getOutputStream();
  7. outputStream.write("hello".getBytes());
  8. //3. 释放资源
  9. socket.close();
  10. }
  11. }

TCP协议接收数据

  1. 创建接收端的Socket对象
  2. 监听客户端连接。返回一个对应的Socket对象
  3. 获取输入流,读取数据显示在控制台
  4. 释放资源
  1. public class ServerDemo {
  2. public static void main(String[] args) throws IOException {
  3. //1. 创建接收端的Socket对象
  4. ServerSocket serverSocket=new ServerSocket(8888);
  5. //2. 监听客户端连接。返回一个对应的Socket对象
  6. Socket socket=serverSocket.accept();
  7. //3. 获取输入流,读取数据显示在控制台
  8. InputStream inputStream=socket.getInputStream();
  9. byte[] bys = new byte[1024];
  10. int len = inputStream.read(bys);
  11. // 阻塞式方法
  12. String str = new String(bys, 0, len);
  13. String ip = socket.getInetAddress().getHostAddress();
  14. System.out.println(ip + "---" + str);
  15. //4. 释放资源
  16. socket.close();
  17. }
  18. }
  • 注意:TCP通信中服务端也可以向客户端发送数据
  1. public class ServerDemo2 {
  2. public static void main(String[] args) throws IOException {
  3. //1. 创建接收端的Socket对象
  4. ServerSocket serverSocket=new ServerSocket(8888);
  5. //2. 监听客户端连接。返回一个对应的Socket对象
  6. Socket socket=serverSocket.accept();
  7. //3. 获取输入流,读取数据显示在控制台
  8. InputStream inputStream=socket.getInputStream();
  9. byte[] bys = new byte[1024];
  10. int len = inputStream.read(bys);
  11. String str = new String(bys, 0, len);
  12. String ip = socket.getInetAddress().getHostAddress();
  13. System.out.println(ip + "---" + str);
  14. //向客户端发送数据
  15. OutputStream outputStream=socket.getOutputStream();
  16. outputStream.write("数据已经收到".getBytes());
  17. //4. 释放资源
  18. socket.close();
  19. }
  20. }
  1. public class ClientDemo2 {
  2. public static void main(String[] args) throws IOException {
  3. //1. 创建发送端的Socket对象:这一步如果成功,就说明连接已经建立成功了。
  4. Socket socket=new Socket("LAPTOP-D9966H06",8888);
  5. //2. 获取输出流,写数据
  6. OutputStream outputStream=socket.getOutputStream();
  7. outputStream.write("hello".getBytes());
  8. //从服务端获取反馈信息
  9. InputStream inputStream=socket.getInputStream();
  10. byte[] bys=new byte[1024];
  11. int len=inputStream.read(bys);
  12. String reback=new String(bys,0,len);
  13. System.out.println("reback:"+reback);
  14. //3. 释放资源
  15. socket.close();
  16. }
  17. }

客户端键盘录入,服务器输出到控制台

  • 服务端:
  1. public class ServerDemo3 {
  2. public static void main(String[] args) throws IOException {
  3. //1. 创建接收端的Socket对象
  4. ServerSocket serverSocket=new ServerSocket(8888);
  5. //2. 监听客户端连接。返回一个对应的Socket对象
  6. Socket socket=serverSocket.accept();
  7. //3. 获取输入流,读取数据显示在控制台
  8. //这里对输入流要进行包装
  9. InputStream inputStream=socket.getInputStream();
  10. BufferedReader br=new BufferedReader(new InputStreamReader(inputStream));
  11. String line=null;
  12. while((line=br.readLine())!=null){
  13. System.out.println(line);
  14. }
  15. //4. 释放资源
  16. socket.close();
  17. }
  18. }
  • 客户端:
  1. public class ClientDemo3 {
  2. public static void main(String[] args) throws IOException {
  3. //1. 创建发送端的Socket对象:这一步如果成功,就说明连接已经建立成功了。
  4. Socket socket=new Socket("LAPTOP-D9966H06",8888);
  5. //键盘录入数据
  6. BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
  7. //2. 获取输出流,写数据
  8. //对输出流进行包装
  9. OutputStream outputStream=socket.getOutputStream();
  10. BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(outputStream));
  11. String line=null;
  12. while(true){
  13. line=br.readLine();
  14. if("-1".equals(line)){
  15. break;
  16. }
  17. bw.write(line);
  18. bw.newLine();
  19. bw.flush();
  20. }
  21. //3. 释放资源
  22. socket.close();
  23. }
  24. }