1 InetAddress

  • 一些常用的方法
  1. //1. 获取本机的InetAddress 对象
  2. InetAddress localHost = InetAddress.getLocalHost();
  3. System.out.println(localHost);
  4. //2. 根据指定主机名 获取 InetAddress对象
  5. InetAddress host1 = InetAddress.getByName("PCOS-2020YWLYDD");
  6. System.out.println("host1=" + host1);
  7. //3. 根据域名返回 InetAddress对象, 比如 www.baidu.com 对应
  8. InetAddress host2 = InetAddress.getByName("www.baidu.com");
  9. System.out.println("host2=" + host2);
  10. //4. 通过 InetAddress 对象,获取对应的地址
  11. String hostAddress = host2.getHostAddress();
  12. System.out.println("host2 对应的ip = " + hostAddress);
  13. //5. 通过 InetAddress 对象,获取对应的主机名/或者的域名
  14. String hostName = host2.getHostName();
  15. System.out.println("host2对应的主机名/域名=" + hostName); // www.baidu.com

2 Socket

2.1 TCP

  • java中TCP的工作流程
    TCP是连接的协议,需要先建立连接再发送数据

Tcp.png

2.1.1 利用TCP传输数据

  • 服务器端
  1. import java.io.*;
  2. import java.net.ServerSocket;
  3. import java.net.Socket;
  4. public class SocketTCPServer {
  5. public static void main(String[] args) throws IOException {
  6. //思路
  7. //1. 在本机 的9999端口监听, 等待连接
  8. // 细节: 要求在本机没有其它服务在监听9999
  9. // 细节:这个 ServerSocket 可以通过 accept() 返回多个Socket[多个客户端连接服务器的并发]
  10. ServerSocket serverSocket = new ServerSocket(9999);
  11. System.out.println("服务端,在9999端口监听,等待连接..");
  12. //2. 当没有客户端连接9999端口时,程序会 阻塞, 等待连接
  13. // 如果有客户端连接,则会返回Socket对象,程序继续
  14. Socket socket = serverSocket.accept();
  15. System.out.println("服务端 socket =" + socket.getLocalSocketAddress());
  16. //
  17. //3. 通过socket.getInputStream() 读取客户端写入到数据通道的数据, 显示
  18. InputStream inputStream = socket.getInputStream();
  19. //4. IO读取, 使用字符流
  20. BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
  21. String s = bufferedReader.readLine();
  22. System.out.println(s);//输出
  23. //5. 获取socket相关联的输出流
  24. OutputStream outputStream = socket.getOutputStream();
  25. // 使用字符输出流的方式回复信息
  26. BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
  27. bufferedWriter.write("hello client 字符流");
  28. bufferedWriter.newLine();// 插入一个换行符,表示回复内容的结束
  29. bufferedWriter.flush();//注意需要手动的flush
  30. //6.关闭流和socket
  31. bufferedWriter.close();
  32. bufferedReader.close();
  33. socket.close();
  34. serverSocket.close();//关闭
  35. }
  36. }
  • 客户端
  1. import java.io.*;
  2. import java.net.InetAddress;
  3. import java.net.Socket;
  4. public class SocketTCPClient {
  5. public static void main(String[] args) throws IOException {
  6. //思路
  7. //1. 连接服务端 (ip , 端口)
  8. //解读: 连接本机的 9999端口, 如果连接成功,返回Socket对象
  9. Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
  10. System.out.println("客户端 socket=" + socket.getLocalSocketAddress());
  11. //2. 连接上后,生成Socket, 通过socket.getOutputStream()
  12. // 得到 和 socket对象关联的输出流对象
  13. OutputStream outputStream = socket.getOutputStream();
  14. //3. 通过输出流,写入数据到 数据通道, 使用字符流
  15. BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
  16. bufferedWriter.write("hello, server 字符流");
  17. bufferedWriter.newLine();//插入一个换行符,表示写入的内容结束, 注意,要求对方使用readLine()!!!!
  18. bufferedWriter.flush();// 如果使用的字符流,需要手动刷新,否则数据不会写入数据通道
  19. //4. 获取和socket关联的输入流. 读取数据(字符),并显示
  20. InputStream inputStream = socket.getInputStream();
  21. BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
  22. String s = bufferedReader.readLine();
  23. System.out.println(s);
  24. //5. 关闭流对象和socket, 必须关闭
  25. bufferedReader.close();//关闭外层流
  26. bufferedWriter.close();
  27. socket.close();
  28. System.out.println("客户端退出.....");
  29. }
  30. }

2.1.1 利用TCP传输文件

  • 服务器端
  1. import java.io.*;
  2. import java.net.ServerSocket;
  3. import java.net.Socket;
  4. public class TCPFileUploadServer {
  5. public static void main(String[] args) throws Exception {
  6. //1. 服务端在本机监听8888端口
  7. ServerSocket serverSocket = new ServerSocket(8888);
  8. System.out.println("服务端在8888端口监听....");
  9. //2. 等待连接
  10. Socket socket = serverSocket.accept();
  11. //3. 读取客户端发送的数据
  12. // 通过Socket得到输入流
  13. BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
  14. byte[] bytes = StreamUtils.streamToByteArray(bis);
  15. //4. 将得到 bytes 数组,写入到指定的路径,就得到一个文件了
  16. String destFilePath = "f\\b.png";
  17. BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
  18. bos.write(bytes);
  19. bos.close();
  20. // 向客户端回复 "收到图片"
  21. // 通过socket 获取到输出流(字符)
  22. BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
  23. writer.write("收到图片");
  24. writer.flush();//把内容刷新到数据通道
  25. socket.shutdownOutput();//设置写入结束标记
  26. //关闭其他资源
  27. writer.close();
  28. bis.close();
  29. socket.close();
  30. serverSocket.close();
  31. }
  32. }
  • 客户端
  1. import java.io.*;
  2. import java.net.InetAddress;
  3. import java.net.Socket;
  4. public class TCPFileUploadClient {
  5. public static void main(String[] args) throws Exception {
  6. //客户端连接服务端 8888,得到Socket对象
  7. Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
  8. //创建读取磁盘文件的输入流
  9. String filePath = "f:\\a.png";
  10. BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
  11. //bytes 就是filePath对应的字节数组
  12. byte[] bytes = StreamUtils.streamToByteArray(bis);
  13. //通过socket获取到输出流, 将bytes数据发送给服务端
  14. BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
  15. bos.write(bytes);//将文件对应的字节数组的内容,写入到数据通道
  16. bis.close();
  17. socket.shutdownOutput();//设置写入数据的结束标记
  18. //=====接收从服务端回复的消息=====
  19. InputStream inputStream = socket.getInputStream();
  20. //使用StreamUtils 的方法,直接将 inputStream 读取到的内容 转成字符串
  21. String s = StreamUtils.streamToString(inputStream);
  22. System.out.println(s);
  23. //关闭相关的流
  24. inputStream.close();
  25. bos.close();
  26. socket.close();
  27. }
  28. }

2.2 UDP

  • UDP是无连接协议
  • 发送数据时先创建套接字绑定本机一个端口,向目的IP和端口发送数据,不需要去管是否有主机在这个端口接收数据

UDP.png

  • A端
  1. import java.io.IOException;
  2. import java.net.DatagramPacket;
  3. import java.net.DatagramSocket;
  4. import java.net.InetAddress;
  5. import java.net.SocketException;
  6. public class UDPReceiverA {
  7. public static void main(String[] args) throws IOException {
  8. //1. 创建一个 DatagramSocket 对象,准备在9999接收数据
  9. DatagramSocket socket = new DatagramSocket(9999);
  10. //2. 构建一个 DatagramPacket 对象,准备接收数据
  11. byte[] buf = new byte[1024];
  12. DatagramPacket packet = new DatagramPacket(buf, buf.length);
  13. //3. 调用 接收方法, 将通过网络传输的 DatagramPacket 对象
  14. // 填充到 packet对象
  15. // 如果没有数据包发送到 本机的9999端口, 就会阻塞等待.
  16. System.out.println("接收端A 等待接收数据..");
  17. socket.receive(packet);
  18. //4. 可以把packet 进行拆包,取出数据,并显示.
  19. int length = packet.getLength();//实际接收到的数据字节长度
  20. byte[] data = packet.getData();//接收到数据
  21. String s = new String(data, 0, length);
  22. System.out.println(s);
  23. //===回复信息给B端
  24. //将需要发送的数据,封装到 DatagramPacket对象
  25. data = "库里FMVP".getBytes();
  26. //说明: 封装的 DatagramPacket对象 data 内容字节数组 , data.length , 主机(IP) , 端口
  27. packet =
  28. new DatagramPacket(data, data.length, InetAddress.getByName("127.0.0.1"), 9998);
  29. socket.send(packet);//发送
  30. //5. 关闭资源
  31. socket.close();
  32. System.out.println("A端退出...");
  33. }
  34. }
  • B端
  1. import java.io.IOException;
  2. import java.net.*;
  3. public class UDPSenderB {
  4. public static void main(String[] args) throws IOException {
  5. //1.创建 DatagramSocket 对象,准备在9998端口 接收数据
  6. DatagramSocket socket = new DatagramSocket(9998);
  7. //2. 将需要发送的数据,封装到 DatagramPacket对象
  8. byte[] data = "hello 勇士总冠军~".getBytes(); //
  9. //说明: 封装的 DatagramPacket对象 data 内容字节数组 , data.length , 主机(IP) , 端口
  10. DatagramPacket packet =
  11. new DatagramPacket(data, data.length, InetAddress.getByName("127.0.0.1"), 9999);
  12. socket.send(packet);
  13. //3.=== 接收从A端回复的信息
  14. //(1) 构建一个 DatagramPacket 对象,准备接收数据
  15. // 在前面讲解UDP 协议时,老师说过一个数据包最大 64k
  16. byte[] buf = new byte[1024];
  17. packet = new DatagramPacket(buf, buf.length);
  18. //(2) 调用 接收方法, 将通过网络传输的 DatagramPacket 对象
  19. // 填充到 packet对象
  20. //老师提示: 当有数据包发送到 本机的9998端口时,就会接收到数据
  21. // 如果没有数据包发送到 本机的9998端口, 就会阻塞等待.
  22. socket.receive(packet);
  23. //(3) 可以把packet 进行拆包,取出数据,并显示.
  24. int length = packet.getLength();//实际接收到的数据字节长度
  25. data = packet.getData();//接收到数据
  26. String s = new String(data, 0, length);
  27. System.out.println(s);
  28. //关闭资源
  29. socket.close();
  30. System.out.println("B端退出");
  31. }
  32. }

常见的网络程序端口号
tomcat:8080
mysql:3306
oracle:1521
sqlserver:1433