Java erlang 套接字通信

Posted

技术标签:

【中文标题】Java erlang 套接字通信【英文标题】:Java erlang socket communication 【发布时间】:2016-09-25 03:16:48 【问题描述】:

我在通过线程读取和写入套接字时遇到问题。服务器使用 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

TransmitterTwo 类:

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() 操作将阻塞,直到服务器有一些响应。

【讨论】:

哇,这比我预期的要好:)。我很绝望,因为我的职业未来取决于这个哈哈。那么,您是否认为通过您的方法,我将能够拥有 N 个客户端并正确获取消息?因为我不想在线程之间传递值,所以我希望每个客户端都与套接字通信并拥有一个独立的发送器/接收器。它就像一个服务,每个客户端都可以通过套接字进行对话和收听......不过,我会尝试这种方法并在之后回答。非常感谢,我真的很感激。 只是一个小错误。发送到套接字的字符串最后总是有一个“\n”,即使使用 trim() 方法,它也会发送一个 \n ...你知道为什么吗? 已修复。必须使用printer.prin 然后刷新,再次感谢。来自葡萄牙的欢呼

以上是关于Java erlang 套接字通信的主要内容,如果未能解决你的问题,请参考以下文章

用 Erlang 与其他人制作的套接字服务器

erlang:如何从套接字接收 HTTP/RTSP 消息?

erlang 发送套接字西里尔文数据

Erlang 套接字发送超时永远不会发生

关闭tcp套接字的erlang

Erlang 增加打开的套接字数量,MacOS 和 CentOs