Java套接字,是死锁还是什么问题?

4

我有一个使用socket的客户端-服务器程序,服务器端进行读写操作。

soc = serversocket.accept();
System.out.println("Accepted");

in = new ObjectInputStream(soc.getInputStream());
out = new ObjectOutputStream(soc.getOutputStream());

if(in.readUTF() == null ? " " != null : !in.readUTF().equals(" "))
{
    diskinfo.setPath(in.readUTF());
}
Item[] pac = diskinfo.get();

out.writeObject(pac);

在客户端(Android)方面同样如此...
Log.v("read", "item");
soc = new Socket(InetAddress.getByName("10.0.2.2"), 3838);
output = new ObjectOutputStream(soc.getOutputStream());
input = new ObjectInputStream(soc.getInputStream());

try 
{
    output.writeUTF(path);
    packets = (Item[]) input.readObject();
} 
catch (ClassNotFoundException e) 
{
    // TODO Auto-generated catch block
    e.printStackTrace();
}

问题在于,连接建立后程序会卡住,没有出现任何错误或异常,只是停止了。

1
这个 if 块真的很难理解。你自己理解了吗?你知道它从输入流中读取了多少次吗? - JB Nizet
是的,我已经更改了。现在我只调用一次in.readObject()并将返回的字符串保存在一个变量中。 - umerk44
2个回答

2

这是一个死锁情况,你必须先创建并刷新ObjectOutputStream。这是因为ObjectInputStream在继续之前会读取OOS发送的头部。


你所提到的死锁只会在两端都先创建ObjectInputStream时发生,而这里并没有发生。 - user207421
@EJP 我怀疑这是对另一个问题的正确答案。 ;) - Peter Lawrey
1
@EJP,我已经尝试了你和Peter建议的两个更改,但是当我应用了你建议的代码时,它仍然无法正常工作。但是当我刷新OutputStream时,代码可以正常工作,即使我撤消了你告诉我的更改。无论如何,感谢你对这个主题的关注和兴趣。 - umerk44

2

这不是死锁,只是糟糕的代码。你一直在调用readUTF(),然后将结果丢弃并再次调用它,好像你调用的次数与发送的内容相同,但实际上并不是这样的。因此,在冗余的readUTF()调用中,你会阻塞

所以不要这样做。只调用一次并将结果存储在变量中。

并且它永远不会返回null。请查看Javadoc。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接