[英]Sending and receiving objects using sockets and threads not working properly
I am currently creating a service allowing to send objects from a client to a server and vice-versa, but experiencing an issue that I unfortunately cannot explain and fix. 我目前正在创建一项服务,该服务允许将对象从客户端发送到服务器,反之亦然,但是遇到一个我不幸无法解释和解决的问题。
First of all, here are the useful classes (I haven't put all methods such as getters and setters in this post). 首先,这里是有用的类(在这篇文章中,我没有放置所有方法,例如getter和setter)。
/**
* This launcher creates a NetworkInterface, waits for a connection, sends a message to the connected client and waits for an incoming message
*
*/
public class ServerLauncher {
public static void main(String[] args) {
try {
NetworkSystem n = new NetworkSystem(4096);
n.startServerManager();
while (n.getCommunications().isEmpty()) {
// this line is unexpectedly magic
System.out.println("Waiting for a new connection...");
}
do {
n.getCommunications().get(0).send(new String("Hello, are you available?"));
} while (n.getCommunications().get(0).getReceiveManager().getReadObjects().isEmpty());
System.out.println(n.getCommunications().get(0).getReceiveManager().getReadObjects().get(0));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* This launcher creates a NetworkSystem, connects to the server, waits for an incoming message and anwers back
*
*/
public class ClientLauncher {
public static void main(String[] args) {
try {
NetworkSystem n = new NetworkSystem(8192);
n.instanciateCommunication(new Socket(InetAddress.getLocalHost(), 4096));
while (n.getCommunications().get(0).getReceiveManager().getReadObjects().isEmpty()) {
// this line is unexpectedly magic
System.out.println("Waiting for an object...");
}
System.out.println(n.getCommunications().get(0).getReceiveManager().getReadObjects().get(0));
n.getCommunications().get(0).getSendManager().send(new String("No, I am not! We will talk later..."));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* This class handles every incoming messages.
*/
public class ReceiveManager implements Runnable {
private ObjectInputStream inputStream;
private CommunicationManager communicationManager;
private List readObjects;
private boolean receive;
public ReceiveManager(CommunicationManager communicationManager) throws IOException {
this.communicationManager = communicationManager;
this.inputStream = new ObjectInputStream(this.communicationManager.getSocket().getInputStream());
this.readObjects = new ArrayList();
this.receive = true;
}
@Override
public void run() {
Object object = null;
try {
while ((object = this.inputStream.readObject()) != null && this.hasToReceive()) {
this.readObjects.add(object);
}
} catch (ClassNotFoundException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
this.setContinueToReceive(false);
}
}
private boolean hasToReceive() {
return this.receive;
}
public void setContinueToReceive(boolean value) {
this.receive = value;
}
}
/**
* This class allows the user to send messages
*/
public class SendManager {
private ObjectOutputStream outputStream;
private CommunicationManager communicationManager;
public SendManager(CommunicationManager communicationManager) throws IOException {
this.communicationManager = communicationManager;
this.outputStream = new ObjectOutputStream(this.communicationManager.getSocket().getOutputStream());
}
public void send(Object object) throws IOException {
this.outputStream.writeObject(object);
this.outputStream.flush();
}
}
So basically, as you may have noticed in the ServerLauncher and the ClientLauncher, there are two "magic" instructions. 因此,基本上,就像您在ServerLauncher和ClientLauncher中注意到的那样,有两个“魔术”指令。 When those two lines are commented and I run the server then the client, nothing happens.
当对这两行进行注释并且我运行服务器然后运行客户端时,什么也没有发生。 The server and the client are simply running and never stop.
服务器和客户端只是在运行,永远不会停止。 However, when I uncomment these two magic lines, every works like a charm: messages are properly sent and received.
但是,当我取消对这两条魔术线的注释时,每条线都像一个符咒:正确发送和接收消息。
Would you guys know the reason of this unexpected behaviour ? 你们知道这种意外行为的原因吗?
Oh yeah, I forgot, if you guys want me to upload everything to test the project or whatever, just tell me :-) 哦,是的,我忘了,如果你们要我上载所有内容以测试项目或进行其他操作,请告诉我:-)
You're starving the CPU with those spin loops. 这些旋转循环使CPU处于饥饿状态。 You should sleep or wait while the queues are empty, or better still just
take()
from blocking queues. 您应该在队列为空时睡眠或等待,或者最好还是从阻塞队列中
take()
。
NB Your loop condition isn't correct: 注意:您的循环条件不正确:
readObject()
doesn't return null
at end of stream. readObject()
在流的末尾不返回null
。 It throws EOFException
. EOFException
。 hasToReceive()
before calling readObject()
rather than afterwards. readObject()
之前而不是之后测试hasToReceive()
。 Otherwise you always do an extra read.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.