Java 为什么client input.readObject有时返回;空";有时效果很好?
我正在尝试制作一个使用tcp java连接的客户机/服务器程序,并使用localhost IP和端口12345在同一台机器(服务器和客户机)上测试它 我使用ObjectInputStream和ObjectOutputStream来接收和发送消息。 有时我的程序运行得很好,它可以根据我的需要发送正确的消息,但是有时(在程序的随机时间/阶段)我的一个客户“失去”连接,他进入无限循环打印“null”或“无效类型代码:54”不进行任何代码更改 我没有收到任何错误,只是服务器在循环中打印“连接重置”,客户端从捕获(IOException e)中打印“空”或“无效类型代码:54” 我将向您展示我的代码的基本内容 服务器:Java 为什么client input.readObject有时返回;空";有时效果很好?,java,sockets,Java,Sockets,我正在尝试制作一个使用tcp java连接的客户机/服务器程序,并使用localhost IP和端口12345在同一台机器(服务器和客户机)上测试它 我使用ObjectInputStream和ObjectOutputStream来接收和发送消息。 有时我的程序运行得很好,它可以根据我的需要发送正确的消息,但是有时(在程序的随机时间/阶段)我的一个客户“失去”连接,他进入无限循环打印“null”或“无效类型代码:54”不进行任何代码更改 我没有收到任何错误,只是服务器在循环中打印“连接重置”,客户
public static void main(String[] args) {
//--------BASIC CODE used for connection stuff below----//
server = new ServerSocket(12345);
connection =server.accept();
Thread thread =new Thread(new ClientThread(connection,GRM...));
thread.start();
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
}
--------------//---------thread for each client----------//--------------
do{
try{
message=(String) input.readObject();
if(message.startsWith("SOMENTHING"))//...some tcode
if(message.equals("SEND")){
String message="hi";
output.writeObject("Chat:"+message);output.flush();
UserW.writeObject(message);UserW.flush();
//UserW is an output from another client stored in the server
}
catch(ClassNotFoundException classNotFoundException){
System.out.print("\nUnknown object");
}catch (IOException e) {
System.out.println(e.getMessage());
}
}while(!message.equals("DISCONNECT"));
客户:
public static void main(String[] args) {
connection=new Socket(InetAddress.getByName("127.0.0.1"),12345);
//...... same logic with streams......//
}
//-------thread that receives from server-----//
do{
try{
String message=(String) input.readObject();
//.....some code....//
}catch( ClassNotFoundException classNotFoundException){
System.out.print("\nUnknown object");
}catch (IOException e) {
System.out.println(e.getMessage());
}
}while(true);
因此,我用我创建的另一个更简单的服务器/客户机程序进行了一些测试 我认为,当服务器同时发送两条或多条消息时,客户端的input.read()会变得“混乱”,无法正确读取消息,从而使服务器进行“连接重置”,客户端会给出“无效代码”错误 我对这个问题的解决方案(有效)是在服务器站点上创建一个向客户端发送消息的同步方法,但我不喜欢它,因为服务器性能会降低(我认为)。作为第二个解决方案,我在客户端站点上考虑制作一些类似缓冲区的东西,但我不知道这是否可行 如果有人有更好的解决办法,我很乐意听 更新:最佳解决方案是使用BufferedReader进行输入,使用PrintWriter进行输出,而不是使用流 另外,非常感谢阿塞托夫,他指引我走上了正确的道路 为什么客户端
readObject()
有时返回null
事实并非如此readObject()
未返回null。您在catch
块中打印null,因为您捕获了一个没有消息的IOException
,例如可能是eofeexception
,这将导致您关闭套接字并中断读取循环
实际问题是一个并发问题,如下所示:
Thread thread =new Thread(new ClientThread(connection,GRM...));
thread.start();
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
输出
和输入
变量应该是ClientThread
的成员,而不是此类,它们应该在ClientThread.run()
中初始化,而不是在其构造函数中初始化,当然也不是在这里初始化 您似乎在同一服务器套接字上打开了两个ObjectOutputStream,这可能是导致此错误的原因。我为每个新连接打开了一个ObjectOutputStream,并在一个新线程中处理它们…如果您的意思是否,我的意思是您的服务器有output.writeObject;UserW.writeObject代码>这似乎表明一个线程(您的服务器)处理两个ObjectOutputStream,这在allOk不是一个好主意我明白您的意思,但我看过一个聊天应用程序的教程,它也做了同样的事情来向其他人广播消息。UserW是存储在服务器中的另一个客户端套接字输出的引用…另一方面,当我必须向其他人发送消息时,我的问题最为明显,因此你可能有一个观点。但是我应该如何向其他人发送消息呢?无需相信我,检查或此处:最坏的情况是,您可以在两个调用之间尝试ObjectOutputStream.reset()
。由于变量作用域错误,您只有多个线程使用相同的流。此解决方案将所有I/O顺序化到所有客户端。一点也不可取。我解决了我的问题,我已经写了答案。我不明白你的意思可能我的java知识不太好