【问题标题】:Sending ArrayList from server side to client side using TCP over socket使用 TCP over socket 将 ArrayList 从服务器端发送到客户端
【发布时间】:2013-03-13 17:45:49
【问题描述】:

我正在尝试将对象从服务器端发送到客户端,但我找不到问题。这是我在客户端遇到的错误:

java.io.StreamCorruptedException: invalid type code: 43
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at connection.MainClient.doAll(MainClient.java:56)
at connection.TestScreen$2.actionPerformed(TestScreen.java:82)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

下面是服务器端方法: 无限循环中的单独方法只是从文件中读取并将用户名和密码解析为 ArrayList,它们是 Server 类中的实例变量。

    public void doStuff() throws Exception
{
    ServerSocket serverSocket = new ServerSocket(5001);
    Socket clientSocket = serverSocket.accept();
    PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
    BufferedReader in = new BufferedReader(
            new InputStreamReader(
            clientSocket.getInputStream()));
    ObjectOutputStream objectOutput = new ObjectOutputStream(clientSocket.getOutputStream());
    String inputLine;
    out.println("Connected");
    while(true)
    {
        seperate();
        while ((inputLine = in.readLine()) != null) 
        {
            if(inputLine.equalsIgnoreCase("users"))
                objectOutput.writeObject(getUserNames());
            else
                if(inputLine.equalsIgnoreCase("pass"))
                    objectOutput.writeObject(getPassWords());
                else
                    if(inputLine.equalsIgnoreCase("stop"))
                        objectOutput.reset();
        }
    }
}

下面是客户端向服务器请求信息:

public boolean doAll(String name, String pass) throws Exception
{
    try 
    {
        kkSocket = new Socket("PC", 5001);
        out = new PrintWriter(kkSocket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
    } 
    catch (UnknownHostException e) 
    {
        System.err.println("Don't know about host: PC.");
        System.exit(1);
    }
    catch (IOException e) 
    {
        System.err.println("Couldn't get I/O for the connection to: PC.");
        System.exit(1);
    }

    ObjectInputStream objectInput = new ObjectInputStream(kkSocket.getInputStream());

    out.println("user");
    Object obj = objectInput.readObject();
    users = (ArrayList<String>)obj;
    out.println("pass");
    obj = objectInput.readObject();
    this.pass = (ArrayList<String>)obj;
    out.println("stop");
    objectInput.close();
    out.close();
    in.close();
    kkSocket.close();

    if(userIsRegistered(name,pass))
        return true;
    return false;
}

我是学习服务器套接字和套接字的新手,但我在这里想要完成的是这个。当我按下另一个班级的按钮时,我会这样做:

MainClient b = new MainClient();
login = b.doAll(userField.getText(),passField.getText());
Login is obviously a boolean.

几乎是服务器上的登录系统,用于在按下登录按钮时调用客户端连接到该服务器并获取存储在指定目录中的文本文件中的服务器上的用户和通行证列表.然后,当客户端收到此信息时,它会检查它是否可能是我从两个文本字段中获取的字符串中的用户,并返回真或假。然后关闭到服务器的套接字,它应该每次都保持重新连接对吗?

我的主要问题是如何修复它不断抛出的错误?

【问题讨论】:

  • @Chuck Norris 第一次写出了完美的代码。 Bug 害怕他的回旋踢,因此他的代码没有错误。
  • @Chuck Norris 错误被视为一项功能。所有开发人员都需要的功能。

标签: java sockets serversocket


【解决方案1】:

你的代码流程如下:

  1. 服务器已启动并等待与客户端的连接
  2. 服务器使用serverSocket.accept() 接受来自客户端的连接。
  3. 服务器通过out.println("Connected")使用PrintWriter对象向客户端发送String消息(“已连接”)。
  4. 客户端正在使用ObjectInputStream 对象读取该消息,这会导致流不匹配,从而违反内部一致性检查。这就是为什么在客户端抛出StreamCorruptedException。所以不要使用ObjectInputStream 来读取服务器发送的纯消息,您应该使用您在上面创建的BufferedReader 对象。

所以在客户端你的代码应该修改为:

ObjectInputStream objectInput = new ObjectInputStream(kkSocket.getInputStream());
String message = in.readLine();//use BufferedReader to read the plain message coming from Server.
System.out.println("Message from server: "+message);
out.println("user");
Object obj = objectInput.readObject();

【讨论】:

    【解决方案2】:

    您不能将InputStreamReader 与字节输入流一起使用。它需要来自输入流的字符/字符串。请改用ObjectInputStream

    提示:输入流类型应该在服务器端和客户端都匹配。你不能混合它们。在您使用ObjectOutputStream的服务器上,因此应在客户端上使用相应的ObjectInputStream

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-24
      • 1970-01-01
      • 2019-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      • 2020-08-08
      相关资源
      最近更新 更多