简体   繁体   English

Java Erlang套接字通信

[英]Java erlang socket communication

i'm having trouble with the socket reading and writing through threads. 我在套接字读取和写入线程时遇到麻烦。 The server's in erlang and the client in Java. 服务器使用erlang,客户端使用Java。 The way i'm doing it is this: 我这样做的方式是这样的:

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

TransmitterTwo Class: 变送器二类:

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();
}
}
}

The Problem is in the main client class. 问题在主要客户类别中。 The idea is to: receive input from the console, send it to the socket, the server handles the logic and sends a response through the socket. 这个想法是:从控制台接收输入,将其发送到套接字,服务器处理逻辑并通过套接字发送响应。 Then on this client I check the response and do whatever i need to do. 然后在此客户端上,我检查响应并执行我需要做的所有事情。 It's a registration flow, i register, i receive "register_ok", then i login...etc etc. The part of the loop where i'm having trouble is this: 这是一个注册流程,我注册后,我收到“ 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;

Is this the right approach? 这是正确的方法吗? The problem is that 'socketmessage' prints the previous received message, it's like..1 step behind, obviously this is thread related but I can't figure out the problem....help? 问题是“ socketmessage”会打印以前收到的消息,就像..1落后一步,显然这与线程有关,但我无法弄清楚问题....帮助? Thanks 谢谢

Your current approach is suboptimal because you're wasting your main thread spinning waiting on that variable to be updated. 您当前的方法是次优的,因为您正在浪费主线程旋转等待该变量进行更新。 Because of how memory visibility works in java it may appear to never be updated (even if it actually is), or you may get stale values when you do access that variable. 由于Java中的内存可见性是如何工作的,因此它似乎永远都不会更新(即使实际上是更新的),或者在您访问该变量时可能会得到陈旧的值。 A more robust approach would be to pass messages between the threads using some of the built in collections in 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();
        }
    }
}

This approach will never get stale values, and the take() operation on the main thread will block until there is some response from the server. 这种方法永远不会获得过时的值,并且主线程上的take()操作将阻塞,直到服务器发出一些响应为止。

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

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