Unix套接字进程通信初探【Java版本】

前文提到了Go语言版本的Unix套接字的实践,作为Java选手,自然也必须安排上。有了Go的经验,Java写起来也比较容易。

Java使用Unix套接字并不是JDK自带的,我们需要引入一个依赖。

<dependency>
    <groupId>com.kohlschutter.junixsocket</groupId>
    <artifactId>junixsocket-core</artifactId>
    <version>2.3.3</version>
</dependency>

Java实现

相比Go语言,Java的代码略显臃肿了。但对于我来讲,Java语言熟悉太多了,跟见了亲人似的。

服务端

服务端跟前文功能一致,启动服务,接收消息,回复消息。

package com.funtest.unix_socket;  
  
import org.newsclub.net.unix.AFUNIXServerSocket;  
import org.newsclub.net.unix.AFUNIXSocketAddress;  
  
import java.io.*;  
import java.net.ServerSocket;  
import java.net.Socket;  
  
/**  
 * Unix Socket 服务端  
 */  
public class UnixSocketServer {  
  
    public static void main(String[] args) throws IOException {  
        File socketFile = new File("/Users/oker/logs/temp/unix_socket_example");// 服务端监听的文件  
        try (ServerSocket server = AFUNIXServerSocket.newInstance()) {// 创建服务端  
            server.bind(new AFUNIXSocketAddress(socketFile));// 绑定文件  
            System.out.println("监听文件: " + socketFile);  
            while (true) {  
                try (Socket socket = server.accept()) {// 接收客户端连接  
                    try (BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));// 读取客户端消息  
                         PrintWriter writer = new PrintWriter(socket.getOutputStream(), true)) {// 回复客户端消息  
                        String line;  
                        while ((line = reader.readLine()) != null) {// 循环读取客户端消息  
                            System.out.println("收到消息: " + line);  
                            writer.println("回复: " + line);// 回复消息  
                        }  
                    }  
                }  
            }  
        }  
    }  
}

客户端

下面是客户端代码,只是发送消息,打印响应。

package com.funtest.unix_socket;  
  
import org.newsclub.net.unix.AFUNIXSocket;  
import org.newsclub.net.unix.AFUNIXSocketAddress;  
  
import java.io.*;  
import java.net.Socket;  
  
/**  
 * Unix Socket 客户端  
 */  
public class UnixScoketClient {  
  
    public static void main(String[] args) throws IOException {  
        File socketFile = new File("/Users/oker/logs/temp/unix_socket_example");// 服务端监听的文件  
        try (Socket socket = AFUNIXSocket.newInstance()) {// 创建客户端  
            socket.connect(new AFUNIXSocketAddress(socketFile));// 连接服务端  
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));// 读取服务端消息  
                 PrintWriter writer = new PrintWriter(socket.getOutputStream(), true)) {// 发送消息给服务端  
                writer.println("Hello FunTester");  
                String response = reader.readLine();// 读取服务端响应  
                System.out.println("收到响应: " + response);  
            }  
        }  
    }  
}

测试互联

经过几次客户端发送消息,下面是服务端打印:

监听文件: /Users/oker/logs/temp/unix_socket_example
收到消息: Hello FunTester
收到消息: Hello FunTester
收到消息: Hello FunTester

下面是客户端打印:

收到响应: 回复: Hello FunTester

进程已结束,退出代码为 0

下面我用Go语言的服务端进行测试,Go服务端打印:

=== RUN   TestServer
服务启动...
收到消息: Hello FunTester

Java客户端打印:

收到响应: null

进程已结束,退出代码为 0

因为原版的Go服务端并没有返回响应,现在加上一行代码,增加消息返回。

// handleConnection 处理连接  
//  
//  @Description: 处理连接  
//  @param conn  
func handleConnection(conn net.Conn) {  
    defer conn.Close()           // 关闭连接  
    buffer := make([]byte, 1024) // 创建一个缓冲区  
    n, err := conn.Read(buffer)  // 读取数据  
    if err != nil {              // 如果读取错误  
       fmt.Println("读取错误:", err)  
       return  
    }  
    conn.Write([]byte("Hello FunTester"))        // 写入数据  
    fmt.Printf("收到消息: %s\n", string(buffer[:n])) // 打印接收到的数据  
}
posted @ 2024-06-03 22:03  FunTester  阅读(14)  评论(0编辑  收藏  举报