这是java中的messenger应用程序。我想发送对象而不仅仅是文本,我认为它要好得多。我正在为每个连接的客户端使用ServerSocketChannel和一个新的Thread。
-Same包,相同的构造函数,相同的 serialVersionUID 。
它只是打印出“之前”命令,无法读取客户端的对象。
服务器代码的一部分:
public static void startServer(){
try{
ServerSocketChannel ssc=ServerSocketChannel.open();
ssc.socket().bind(new InetSocketAddress(hostName,portNumber));
while(isServerRunning()){
removeLoggedOutClients();
try{
SocketChannel sc=ssc.accept();
Socket s=sc.socket();
ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
Client cli=null;
System.out.println("before");
cli=(Client)ois.readObject();
System.out.println("after");
ois.close();
if(checkLogin(cli)){
System.out.println(cli.getUsername()+" signed in.");
cli.setSocket(s);
ClientThread ct=new ClientThread(s,cli.getClientID());
ct.setDaemon(true);
clientThreads.add(ct);
ct.start();
}
}
catch(Exception e){
Error err=new Error("Server","void startServer()",2,e.toString());
}
}
}
catch(Exception e){
Error err=new Error("Server","void startServer()",1,e.toString());
}
}
客户代码的一部分:
public static void connectToServer(Client user){
try{
SocketChannel sc=SocketChannel.open();
sc.configureBlocking(true);
sc.connect(new InetSocketAddress(serverHostName,serverPortNumber));
Socket s=sc.socket();
ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
oos.writeObject(user);
oos.flush();
RecieveThread rt=new RecieveThread(s,ois,user);
rt.setDaemon(true);
rt.start();
setOut(oos);
}
catch(Exception e){
Error err=new Error("Client","connectToServer(Client user)",1,e.toString());
}
}
(我的“错误”类的目的是将所有可能的异常插入数据库。)
答案 0 :(得分:1)
主要问题是您在客户端中创建ObjectInputStream
:这将阻止,直到创建对等中的ObjectOutputStream
,并且您没有创建一个,至少不在您发布的代码中。您需要立即按顺序创建ObjectOutputStream
然后ObjectInputStream,
两端。
但是你还有一个问题。除了接受连接之外,您不应该在接受循环中执行任何I / O操作。所有对象流创建,登录等都应该在为处理连接而创建的线程中完成,而NB不在其构造函数中,而是在其run()
方法中。否则,一个流氓或故障客户端可能会阻止整个系统。