【发布时间】:2015-06-17 22:25:51
【问题描述】:
我正在尝试使用套接字在 Java 中编写客户端和服务器之间的简单交互。
服务器
public class MyServer
{
private static final int SPORT = 4444;
ServerSocket server;
Socket client;
ObjectInputStream is;
ObjectOutputStream os;
/**
* Constructor
*/
public MyServer() {
try
{
server = new ServerSocket(SPORT);
}
catch (IOException e)
{
e.printStackTrace();
}
listenAndReply();
}
public void listenAndReply()
{
System.out.println("Server running.");
System.out.println("Waiting for connection...");
try
{
client = server.accept();
System.out.println("Connection accepted. \n");
is = new ObjectInputStream(client.getInputStream());
os = new ObjectOutputStream(client.getOutputStream());
while(! client.isClosed()) {
Object o = is.readObject();
// ... process object ...
}
}
catch (IOException | ClassNotFoundException e)
{
e.printStackTrace();
}
}
public void sendCommand(Command c) {
try
{
os.reset();
os.writeObject(c);
os.flush();
}
catch (IOException e)
{
e.printStackTrace();
}
}
客户
public class MyClient implements ChatClient
{
private static final int SPORT = 4444;
private static final String SHOST = "127.0.0.1";
Socket socket;
ObjectInputStream is = null;
ObjectOutputStream os = null;
public MyClient() {
try
{
socket = new Socket(SHOST, SPORT);
os = new ObjectOutputStream(socket.getOutputStream());
is = new ObjectInputStream(socket.getInputStream());
System.out.println("Client socket created.");
}
catch (Exception e)
{
e.printStackTrace();
}
}
@Override
public Command receive()
{
try
{
Object o = is.readObject();
if(o instanceof Command) {
System.out.println("Received command: " + o.getClass().getSimpleName());
return (Command) o;
}
}
catch (IOException | ClassNotFoundException e)
{
e.printStackTrace();
}
return null;
}
public void sendCommand(Command c) {
System.out.println("Client sending command " + c.getClass().getSimpleName());
try
{
os.reset();
os.writeObject(c);
os.flush();
System.out.println("Command sent. \n");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
你能看出哪里不对吗?问题是,如果我尝试交换多个对象,我会得到
java.io.StreamCorruptedException:无效类型代码:00
编辑 - 已解决
最后我设法解决了这个问题:正如 Pshemo 所怀疑的那样,问题不在这段代码中,而是在另一个类中,那里有另一个对接收方法的调用,这显然导致了奇怪的行为。现在我将不得不重新考虑一下结构,但至少套接字通信看起来不错。
【问题讨论】:
-
os.reset();在sendCommand中的作用是什么? -
它应该重置流以使其看起来像一个新打开的流,正如我在另一个问题中所读到的。无论如何,忽略它并不会改变结果。
-
我无法重现您的错误。您可以创建并发布SSCCE(简短但完整的代码可以重现您的问题)吗?
-
其实这只是一个更大项目的一小部分。我以为我只是在对象流上犯了一些愚蠢的错误,所以我试图削减其他所有内容,只发布与对象交换相关的代码
-
是的,我意识到,但是创建 SSCCE 有很多优点:(1) 它可以帮助您缩小问题范围 (2) 这使得回答更容易 (3) 它可以帮助未来的读者更容易地测试他们是否面临类似的问题问题。所以我建议无论如何都要创建它,因为第 1 点(我在创建 SSCCE 时经常在我的代码中发现问题,所以真的值得花相当多的时间来创建它)。
标签: java sockets serialization