[英]Client freeze on reading object from socket
我正在通过套接字开发一个简单的Client-Server应用程序,但是我不明白为什么客户端在读取对象时会冻结。 服务器必须能够处理多个客户端。
保持简单,我的服务器看起来像:
...
server_thread = new Thread(new Runnable() {
@Override
public void run() {
int p = 0;
ObjectInputStream in;
ObjectOutputStream out;
NetworkOffer message;
try (ServerSocket serverSocket = new ServerSocket(port)) {
// get connections
LinkedList<Socket> client_sockets = new LinkedList<>();
while (p++ < partecipants) client_sockets.add(serverSocket.accept());
// sending welcome object
for (Socket socket : client_sockets) {
out = new ObjectOutputStream(socket.getOutputStream());
message = new NetworkOffer();
out.writeObject(buyer_offer);
}
...
我的客户:
...
client_thread = new Thread(new Runnable() {
@Override
public void run() {
ObjectInputStream in;
NetworkOffer smessage;
try {
Socket ssocket = new Socket("localhost", port);
in = new ObjectInputStream(ssocket.getInputStream());
// waiting server message
------------->Object o = in.readObject();
smessage = (NetworkOffer)o;
System.out.println(smessage.toString());
...
编辑 :为了使事情更清楚,这是我要实现的协议:
服务器向客户发送welcome
每个客户报价
Accept/Reject
向每个客户端发送消息 客户端坚持Object o = in.readObject();
即使服务器已经发送了他的消息。 没错,没事。 线程只是冻结在那里等待某事。
这是怎么回事?
问题是ServerSocket.accept()
是一个阻塞调用,这意味着服务器将挂起,直到有人连接到它为止。 当有人连接时,服务器会将新套接字添加到client_sockets
。 如果添加的套接字数少于participants
,那么它将再次调用accept()
并等待另一个连接。 仅当套接字的总数等于participants
时,才进入for
循环。 您需要产生一个新线程来处理每个传入的客户端套接字,并允许服务器立即返回ServerSocket.accept()
。 看一下Reactor模式,以了解如何实现此示例。
您的代码应如下所示:
client_sockets
列表中,并等待客户端提供。 Accept/Reject
消息。 就像我之前说过的:您确定服务器已将数据发送到客户端-没有缓冲区刷新,因此仍可以对其进行缓存。
out.flush()
将确保缓冲区被刷新。 分别处理客户端并向其发送定期消息以更新有关状态的信息将是有意义的。
对于您的服务器代码来说,处理客户端断开/连接断开也很有用。
在侧面说明:
message = new NetworkOffer();
out.writeObject(buyer_offer);
您的代码似乎正在发送示例中未包含的其他内容。 那是对的吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.