java - 与套接字交换对象

标签 java sockets serialization

我正在尝试使用套接字在 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 怀疑的那样,问题不在这段代码中,而是在另一个类中,其中再次调用了 receive 方法,这显然导致了奇怪的行为。现在我必须重新考虑一下结构,但至少套接字通信看起来不错。

最佳答案

在服务器类中,您尝试从客户端获取输入和输出,但在客户端类中,您将游览客户端套接字设置为套接字而不是客户端。您试图通过类而不是套接字提取信息,所以我猜这就是您的问题。如果我错了请纠正我

public class MyServer{

private static final int SPORT = 4444;



/**
* Constructor
*/
public MyServer() {
try
{
  ServerSocket 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
{
  socket = server.accept();

  System.out.println("Connection accepted. \n");

  InputStream is = new InputStream(socket.getInputStream()); //changed from client.getInputStream() because in your client class you have setup your client socket to be named socket instead of client.
  OutputStream os = new OutputStream(socket.getOutputStream()); //changed from client.getOutputStream() since your client class has a differently named client socket, your server can’t get information from it by calling client.get

  while( !socket.isClosed()) {

    Object o = is.readObject();

    // ... process object ...

  }
}
catch (IOException | ClassNotFoundException e)
{
  e.printStackTrace();
}

}

关于java - 与套接字交换对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29591283/

相关文章:

c# - TcpClient.Dispose() 是否关闭 TcpClient.GetStream?

c - 关闭 IPV6_V6ONLY 或两个监听套接字

c# - 序列化相似的类

json - Newtonsoft.JSON 使用 GUID 序列化\反序列化数据表

java - 创建菜单但两个按钮之一无法正常工作

java - 用于 String.format() 的 Java 中 %ld 的 C++ 等价物

php - 如何使用 PHP 创建到同一主机的多个持久套接字连接 TCP/IP

c++ - 如何为套接字编程序列化 8 位整数结构?

java - IBM Websphere 命令缓存失效

java - 多线程——更快的方法?