簡體   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