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 套接字通信的主要内容,如果未能解决你的问题,请参考以下文章