打算将 Socket 编程再复习下,为后续学习 netty 做准备。
知识准备
学习 Socket 编程,一些前置知识必不可少。
OSI 参考模型以及 TCP/IP 协议栈。		
 
网络编程三要素:协议、IP 和端口号。		
 
端口号是正在运行的程序的标识;有效的端口号范围:0 到 65535,其中 0 到 1024 为系统使用或保留。  
 
TCP/IP 是对一组协议的统称,具体每一层都有很多协议。传输层的协议主要关注 TCP 和 UDP。
 
UDP 的特点是无连接、速度快、不可靠,需要将数据打包,有大小限制。
 
TCP 的特点是有连接(三次握手、四次挥手),速度相比 UDP 要慢,但要可靠,数据无限制。	
 
Socket 编程,即为网络编程,也称为套接字编程。Socket 是网络上具有唯一标识的 IP 地址和端口号组合在一起构成。Socket 通信的两端都有 Socket,网络通信即为 Socket 间的通信,数据在两个 Socket 间在某种协议下通过 IO 流传输。
 
API 学习
关于 Java Socket 的源码都在 net 包下,其中有几个比较重要的类 InetAddress 和 URL 等等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
   | package com.nekolr;
  import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.InetAddress; import java.net.URL;
 
 
 
  public class APIDemo {
      public static void main(String[] args) throws Exception {
          
 
 
 
                   InetAddress address = InetAddress.getLocalHost();                  String hostName = address.getHostName();                  String ip = address.getHostAddress();
          
 
 
 
 
 
 
                   byte []bytes = address.getAddress();                  InetAddress address1 = InetAddress.getByName("avalon");         InetAddress address2 = InetAddress.getByName("192.168.229.1");                  InetAddress address3 = InetAddress.getByAddress(bytes);
 
          
 
 
 
          URL baidu = new URL("http://www.baidu.com");
          URL url = new URL(baidu, "/index.html?username=nekolr#test");                  url.getProtocol();                  url.getHost();                  url.getPort();                  url.getPath();                  url.getFile();                  url.getRef();                  url.getQuery();
 
          
 
 
                   InputStream is = baidu.openStream();                  InputStreamReader isr = new InputStreamReader(is, "utf-8");                  BufferedReader br = new BufferedReader(isr);         String line = br.readLine();         while (line!=null){             System.out.println(line);             line = br.readLine();         }         br.close();         isr.close();         is.close();
                   try (BufferedReader reader = new BufferedReader(new InputStreamReader(baidu.openStream(), "utf-8"))) {             String data;             while((data = reader.readLine())!=null){                 System.out.println(data);             }         } catch (IOException e) {             e.printStackTrace();         }     } }
   | 
 
简单 Socket 通信练习
Socket 通信基于 TCP 和 UDP 协议,针对这两个协议有不同的写法。
		
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
   | import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.*;
  public class TcpSocket {
      static class TcpServer implements Runnable {         private int port;
          public TcpServer(int port) {             this.port = port;         }
          @Override         public void run() {             ServerSocket serverSocket = null;             BufferedReader reader = null;             BufferedWriter writer = null;             try {                                  serverSocket = new ServerSocket(this.port);                                  Socket socket = serverSocket.accept();                                  reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));                 System.out.println("Client Message:" + reader.readLine());
                  writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));                 writer.write("Hello Client");                                  writer.newLine();                 writer.flush();             } catch (Exception e) {                 e.printStackTrace();             } finally {                 try {                     if (serverSocket != null) serverSocket.close();                     if (reader != null) reader.close();                     if (writer != null) writer.close();                 } catch (Exception e) {                     e.printStackTrace();                 }             }         }     }
      static class TcpClient implements Runnable {         private String host;         private int port;
          public TcpClient(String host, int port) {             this.host = host;             this.port = port;         }
          @Override         public void run() {             Socket socket = null;             BufferedWriter writer = null;             BufferedReader reader = null;             try {                                  socket = new Socket(this.host, this.port);                                  writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));                 writer.write("Hello Server");                                  writer.newLine();                 writer.flush();                                  reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));                 System.out.println("Server Message:" + reader.readLine());             } catch (Exception e) {                 e.printStackTrace();             } finally {                 try {                     if (socket != null) socket.close();                     if (reader != null) reader.close();                     if (writer != null) writer.close();                 } catch (Exception e) {                     e.printStackTrace();                 }             }         }     }
      public static void main(String[] args) {         TcpServer tcpServer = new TcpServer(8888);         TcpClient tcpClient = new TcpClient("localhost", 8888);
          ExecutorService executor = new ThreadPoolExecutor(2, 2,                 0L, TimeUnit.MILLISECONDS,                 new LinkedBlockingQueue<>(1024), new ThreadPoolExecutor.AbortPolicy());
          executor.execute(tcpServer);         executor.execute(tcpClient);     } }
   | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
   | import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.util.concurrent.*;
  public class UdpSocket {
      static class UdpServer implements Runnable {         
 
          private int clientPort = 10088;
          
 
          private int serverPort = 10086;
          private String host = "localhost";
          @Override         public void run() {                          try (DatagramSocket socket = new DatagramSocket(serverPort)) {                                  byte[] bytes = "我是服务端,消息为:i'm server".getBytes();                 DatagramPacket sendPacket = new DatagramPacket(bytes, bytes.length, InetAddress.getByName(host), clientPort);                                  socket.send(sendPacket);
                  bytes = new byte[1024];                 DatagramPacket receivePacket = new DatagramPacket(bytes, bytes.length);                                  socket.receive(receivePacket);
                  System.out.println("服务端接收的消息为:" + new String(bytes, "utf-8"));             } catch (SocketException e) {                 e.printStackTrace();             } catch (IOException e) {                 e.printStackTrace();             }         }     }
      static class UdpClient implements Runnable {         
 
          private int clientPort = 10088;         
 
          private int serverPort = 10086;
          private String host = "localhost";
          @Override         public void run() {                          try (DatagramSocket socket = new DatagramSocket(clientPort)) {                                  byte[] bytes = "我是客户端,消息为:i'm client".getBytes();                 DatagramPacket sendPacket = new DatagramPacket(bytes, bytes.length, InetAddress.getByName(host), serverPort);                                  socket.send(sendPacket);
                  bytes = new byte[1024];                 DatagramPacket receivePacket = new DatagramPacket(bytes, bytes.length);                                  socket.receive(receivePacket);
                  System.out.println("客户端接收的消息为:" + new String(bytes, "utf-8"));
              } catch (SocketException e) {                 e.printStackTrace();             } catch (IOException e) {                 e.printStackTrace();             }         }     }
      public static void main(String[] args) {         UdpServer udpServer = new UdpServer();         UdpClient udpClient = new UdpClient();
          ExecutorService executor = new ThreadPoolExecutor(2, 2,                 0L, TimeUnit.MILLISECONDS,                 new LinkedBlockingQueue<>(1024), new ThreadPoolExecutor.AbortPolicy());
          executor.execute(udpServer);         executor.execute(udpClient);     } }
   |