繁体   English   中英

Java Erlang套接字通信

[英]Java erlang socket communication

我在套接字读取和写入线程时遇到麻烦。 服务器使用erlang,客户端使用Java。 我这样做的方式是这样的:

PrintWriter printer = new PrintWriter(socket.getOutputStream(), true);
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
TransmitterTwo trans = new TransmitterTwo(socket);
trans.start(); // Gets the message from socket

变送器二类:

public class TransmitterTwo extends Thread {
Socket socket;
String message;

TransmitterTwo(Socket socket) {
  this.socket = socket;
}

public String getMessageFromSocket() {
  return message;
}

public void run() {
  try {
    String response = null;
    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  while ((response = reader.readLine()) != null) {
    System.out.println("Server response: "+ response);
    this.message = response;
  }

  socket.close();
} catch(IOException e) {
  e.printStackTrace();
}
}
}

问题在主要客户类别中。 这个想法是:从控制台接收输入,将其发送到套接字,服务器处理逻辑并通过套接字发送响应。 然后在此客户端上,我检查响应并执行我需要做的所有事情。 这是一个注册流程,我注册后,我收到“ register_ok”,然后我登录...等。我遇到麻烦的循环部分是:

while(true) {
  String readerInput = reader.readLine(); // Read from console
  printer.println(readerInput.trim()); // Sends it to the socket

  while(trans.message == null);
  socketMessage = trans.message;

这是正确的方法吗? 问题是“ socketmessage”会打印以前收到的消息,就像..1落后一步,显然这与线程有关,但我无法弄清楚问题....帮助? 谢谢

您当前的方法是次优的,因为您正在浪费主线程旋转等待该变量进行更新。 由于Java中的内存可见性是如何工作的,因此它似乎永远都不会更新(即使实际上是更新的),或者在您访问该变量时可能会得到陈旧的值。 一种更可靠的方法是使用Java中的一些内置集合在线程之间传递消息:

public static void main(String[] args) {
    // This queue will be the link between the threads where 
    // they can pass messages to each other
    BlockingQueue<String> messages = new LinkedBlockingQueue<>();

    PrintWriter printer = new PrintWriter(socket.getOutputStream(), true);
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    TransmitterTwo trans = new TransmitterTwo(socket, queue);
    trans.start(); // Gets the message from socket

    ...

    while(true) {
          String readerInput = reader.readLine(); // Read from console
          printer.println(readerInput.trim()); // Sends it to the socket

          // Wait for the other thread to push a message in to the queue.
          String recv = messages.take();
    }
}

public class TransmitterTwo extends Thread {
    final Socket socket;
    final BlockingQueue<String> queue;

    TransmitterTwo(Socket socket, BlockingQueue<String> queue) {
        this.socket = socket;
        this.queue = queue;
    }

    public void run() {
        try {
            String response = null;
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            while ((response = reader.readLine()) != null) {
                System.out.println("Server response: " + response);
                // Add the response from the server to the queue
                queue.add(response);
            }

            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

这种方法永远不会获得过时的值,并且主线程上的take()操作将阻塞,直到服务器发出一些响应为止。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM