2017-05-24 60 views
0

我想从我的服务器应用程序将同一个套接字上的两个不同对象发送到我的客户端应用程序。从我读过的内容中,我以正确的方式做到了这一点,但仍然无法将第二个对象发送给我的客户。为什么我得到Software导致连接中止:套接字写入错误?

这里是我的服务器代码:

public class ServerThread implements Runnable { 

String name = null; 
Socket socket = null; 

public ServerThread(Socket s, String name) { 
    this.name = name; 
    this.socket = s; 
} 

@Override 
public void run() { 

    try { 
     ObjectOutputStream serverOutputStream = new ObjectOutputStream(socket.getOutputStream()); 
     ObjectInputStream serverInputStream = new ObjectInputStream(socket.getInputStream()); 
     RequestType request = (RequestType) serverInputStream.readObject(); 
     switch (request) { 
      case LOGIN: 
       serverInputStream = new ObjectInputStream(socket.getInputStream()); 
       RequestManager.manageLogin(serverOutputStream, serverInputStream); 
       serverOutputStream = new ObjectOutputStream(socket.getOutputStream()); 
       RequestManager.managePopulateTable(serverOutputStream); 
     } 
     serverOutputStream.close(); 
     serverInputStream.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

}

这是我的服务器请求管理器

public class RequestManager { 

public static void manageLogin(ObjectOutputStream serverOutputStream, ObjectInputStream serverInputStream) { 
    ArrayList<ProductEntity> availableProducts = new ArrayList<>(); 
    try { 
     UserEntity loggedUser = (UserEntity) serverInputStream.readObject(); 
     if (DatabaseManager.userConnect(loggedUser.getUsername(), loggedUser.getPassword())) { 
      serverOutputStream.writeObject(loggedUser); 
     } 
     else 
      serverOutputStream.writeObject(null); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

public static void managePopulateTable(ObjectOutputStream serverOutputStream) { 
    ArrayList<ProductEntity> availableProducts = DatabaseManager.getProducts(); 
    try { 
     serverOutputStream.writeObject(availableProducts); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

}

出现的问题,当我尝试发送“ availableProducts“给客户。

+1

停止创建和关闭新的对象流,并在两端使用与套接字的生命周期相同的流。 – EJP

回答

0

您已经有很多用下面的代码的问题:

ObjectOutputStream serverOutputStream = new ObjectOutputStream(socket.getOutputStream()); 
ObjectInputStream serverInputStream = new ObjectInputStream(socket.getInputStream()); 
... 
switch (request) { 
    case LOGIN: 
     serverInputStream = new ObjectInputStream(socket.getInputStream()); 
     ... 
     serverOutputStream = new ObjectOutputStream(socket.getOutputStream()); 

当您打开一个ObjectOutputStream,报头信息写入到流来帮助管理对象序列化。同样,当您打开ObjectInputStream时,将从流中读取标题信息。

但是,在这里,您打开第二个ObjectInputStream(它将从相同套接字流中读取标头信息)和第二个ObjectOutputStream(它会将头信息写入同一个套接字流)。结果,套接字上的对象流将处于不良状态 - 对象应该遵循标题信息,而不是另一个对象流标题。

不要多次打开对象流。

+0

对于我的serverInputStream,如果我不打开第二个ObjectInputStream它会引发“java.io.StreamCorruptedException:无效的类型代码:AC”。对于serverOutputStream,即使我没有打开第二个ObjectOutputStream,我也会得到相同的错误 –

+0

听起来您的客户端代码可能类似,并在同一个套接字输出流中打开第二个ObjectOutputStream。只能套用一个套接字流(实际上是任何流)一次。 – AJNeufeld

相关问题