RPC协议

Java网络通信

Java中提供了一套网络API用于网络通信,可以使用这套API进行分布式网络通信。其中就包含UDP与TCP以及组播Multicast的实现:

# 这些类都是对传输层,即TCP和UDP协议的封装

UDP:
    DatagramSocket
    DatagramChannel
TCP
    Socket/ServerSocket
    SocketChannel
Multicast
    MulticastSocket

注:组播

  1. 单播,点对点通信

  2. 广播,一对多通信

  3. 组播,介于单播和广播之间,针对组进行通信

除此之外,也可以基于开源框架进行分布式通信,比如Mina、Netty等,你可以理解他们是对socket的封装和增强。

Socket/ServerSocket

必须拥有以下几个条件才能保证两台服务器之间可以通信,所以在任何网络API中,这些条件都是必须指定的参数或者属性:

  • IP地址

  • 端口

  • 通信协议

示例代码

// Socket服务端
public class SocketServer {

    public static void main(String[] args) throws Exception {
        ServerSocket server = new ServerSocket(8888);
        while (true) {
            final Socket socket = server.accept();
            new Thread() {
                @Override
                public void run() {
                    try {
                        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        PrintWriter writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
                        while (true) {
                            //读取客户端发送过来的消息
                            String line = reader.readLine(); 
                            if (line == null) {
                                break;
                            } else {
                                System.out.println(System.currentTimeMillis() +  "服务端收到数据:" + line);
                            }
                            //给客户端发送一条消息回复
                            writer.println(" - 我收到了你的消息,客户端");
                            writer.flush();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        }
    }
}

// Socket客户端
public class SocketClient {

    public static void main(String[] args) throws Exception {
        Socket socket = new Socket("localhost", 8888);
        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); //读取服务端信息
        PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);  // 往服务端写数据
        writer.println("你好,服务端");
        while (true) {
            String serverData = reader.readLine();
            if (serverData == null) {
                break;
            } else {
                System.out.println(System.currentTimeMillis() + " - 客户端收到数据:" + serverData);
            }
        }
        writer.close();
        socket.close();
    }
}

Multicast

Java组播示例:

/**
 * 组播
 * 如果你在大街上喊一声美女,将会有一组人(女)回头看你
 */
public class Multicast {

    public static class MulticastServer {
        public static void main(String[] args) {
            try {
                //  组定义
                //  组的地址端处于 224.0.0.0 - 239.255.255.255
                InetAddress group = InetAddress.getByName("224.5.5.6");
                MulticastSocket server = new MulticastSocket();
                for (int i = 0; i < 10; i++) {
                    String data = "你好年轻人";
                    server.send(new DatagramPacket(data.getBytes(), data.getBytes().length, group, 8888)); // DatagramPacket: UDP数据包
                    TimeUnit.SECONDS.sleep(2);
                }
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static class MulticastClient {
        public static void main(String[] args) {
            try {
                InetAddress group = InetAddress.getByName("224.5.5.6");
                MulticastSocket client = new MulticastSocket(8888);
                client.joinGroup(group); // 加入指定的组中
                byte[] buf = new byte[256];
                while (true) {
                    DatagramPacket msgPkg = new DatagramPacket(buf, buf.length);
                    client.receive(msgPkg);
                    
                    String msg = new String(msgPkg.getData());
                    System.out.println(msg);
                }
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}

最后更新于