抛出readObject间歇性classCastException

时间:2015-04-15 15:58:02

标签: java android multithreading sockets casting

我正在开发简单的Android到Java应用程序,我希望它们与类Message进行通信,如下所示:

public class Message implements Serializable {

/**
 *
 */
private static final long serialVersionUID = 120L;
private MessageType type;
private Object content;

public Message(MessageType type, Object content) {
    this.type = type;
    this.content = content;
}

public String toString() {
    StringBuilder string = new StringBuilder();
    string.append(type).append(System.getProperty("line.separator"));
    if (content != null) {
        string.append(content.toString());
    }
    return string.toString();
}
//======== Getters and Setters ===========
...

}

对象内容始终是User,非常简单。

现在,Java服务器接收Android注册请求,并回答可用用户列表。 还有一些其他请求/响应通信,但它不是重点。

现在,有时我对Android客户端和Java服务器之间的通信没有任何问题,但有时会抛出classCastException(在Android和Java上)。

我在两侧都有两个线程,用于在同一个套接字上发送和接收消息。 我是否必须制作两个单独的插座用于发送和接收,我怀疑?

有没有人有这个想法或经验? 是否与多线程或互联网连接无关?

修改 在Message中对象content字段的类型是灵活的(我需要它在这里传递一些其他类,但是现在,我总是发送用户类:

public class User implements Serializable {
/**
 *
 */
private static final long serialVersionUID = 123L;
private String name;
private String IP;
private int tcpPort;
private int bufferSize;

public User(User user) {
    this.name = new String(user.name);
    this.IP = new String(user.IP);
    this.tcpPort = user.tcpPort;
    this.bufferSize = user.bufferSize;
}

public Integer getHashCode() {
    return ((String) (IP + tcpPort)).hashCode();
}

public String toString() {
    StringBuilder string = new StringBuilder();
    string.append(name).append(System.getProperty("line.separator"));
    string.append(IP).append(System.getProperty("line.separator"));
    string.append(tcpPort).append(System.getProperty("line.separator"));
    return string.toString();
}

这是简单的用户类。

这是我在服务器端做的事情: - 服务器接收等待来自客户端的新请求并将其添加到新连接列表 - Waiter.pendingConnections(if语句)。 - 如果没有新请求,则线程将从soTimeout周期开始接收来自现有连接的新消息。 注意:ClientTcpConnectorServerTcpConnector是套接字,输入和输出流以及东西的包装器(由于复杂性,我现在不会发布这些类...)

public class DispatchingManager extends Thread {
    private final static Logger Log = LogManager.getLogger(Connector.class.getName());

    private static final int SERVER_WAITING_PORT = 50001;
    public static final ServerTcpConnector syncConnector = new ServerTcpConnector(SERVER_WAITING_PORT);
    private final int SOCKET_TIMEOUT_PERIOD = 300;

    @Override    public void run() {
        /* InetAddress remoteIPaddress = syncConnector.waitConnection(); */
        ClientTcpConnector awaitedConnector;
        boolean isReceived = false;
        while (!isInterrupted()) {
            //wrapper for socket.accept() with soTimeout argument
            awaitedConnector = syncConnector.waitRequest(SOCKET_TIMEOUT_PERIOD);
            if (awaitedConnector != null) {
                Log.debug("New connection - available");
                awaitedConnector.connect();
                awaitedConnector.receive();
                Waiter.pendingConnections.addFirst(new CompleteUser(null, awaitedConnector));
            } else {
                for (CompleteUser user : Waiter.onlineConnections.values()) {
                    awaitedConnector = (ClientTcpConnector) user.getConnector();

                    isReceived = awaitedConnector.receive(SOCKET_TIMEOUT_PERIOD);

                    if (isReceived) {
                        Log.debug("Message received from: " + user.getNetworkUser().getName());
                        Waiter.pendingConnections.addFirst(user);
                        isReceived = false;
                    }

                }
            }
        }
    }
}

我的服务器设计为几乎没有线程接收来自Waiter.pendingConnections的请求,并通过对客户端的响应来处理它们。现在我只有一个线程处理挂起的连接。

在客户端这是(非常相似): 这是WelcomeActivity之后的主要线程。

...

@Override
    public void run() {
        tcpConnector = new TcpConnector(remoteServerIP, remoteServerPort);
        while (true) {
            registerWithServer();
            sendTCPThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    sendDataToServer();
                }
            }, "sendTCPThread");
            sendTCPThread.start();
            waitNewServerMessages();
            sendTCPThread.interrupt();
        }
    }

private void sendDataToServer() {
        while (!Thread.interrupted()) {
            try {
                Message message = getSendingMessageQueue().takeFirst();
                tcpConnector.send(message);
                Log.d(TAG, "Sent message - " + message.toString());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private static boolean waitNewServerMessages() {
        Message newMessage;
        while (!syncManager.interrupted()) {
            newMessage = (Message) tcpConnector.receiveObject();
            if (newMessage != null) {
                switch (newMessage.getType()) {
                    case NEW_USER:
                        onlineUsers.add((User) newMessage.getContent());
                        updateUIWith((User) newMessage.getContent(),
                                     AppState.IDLE);
                        break;

                    case END_ADDING:
                        break;

                    case DISCONNECTED_USER:
                        updateUIWith((User) newMessage.getContent(),
                                     AppState.DISCONNECTED_USER);
                        break;

                    case DISCONNECT:
                        syncManager.interrupt();
                        break;

                    default:
                        break;
                }
                Log.d(TAG, "Receive message - " + newMessage.toString());
            }
        }
        return true;
    }

基本上这是接收和发送消息的结构,代码太长而无法完全发布,但我可以做到......

最大的问题是我有时可以完成沟通,但有时我不能......我知道我发送接收代码是好的,因为有时一切都还可以。但另一方面我不知道如何调试它,因为它有时会抛出这个异常:

    11:48:34.002 [Thread-1] DEBUG networkUtils.connectors.Connector - ClassCastException: 
java.lang.ClassCastException: java.io.ObjectStreamClass cannot be cast to networkUtils.networkMessage.Message
    at networkUtils.connectors.ClientTcpConnector.receive(ClientTcpConnector.java:42) [bin/:?]
    at networkUtils.connectors.ClientTcpConnector.receive(ClientTcpConnector.java:75) [bin/:?]
    at networkUtils.DispatchingManager.run(DispatchingManager.java:37) [bin/:?]
11:48:34.609 [Thread-1] DEBUG networkUtils.connectors.Connector - ClassCastException: 
java.lang.ClassCastException: networkUtils.beans.User cannot be cast to networkUtils.networkMessage.Message
    at networkUtils.connectors.ClientTcpConnector.receive(ClientTcpConnector.java:42) [bin/:?]
    at networkUtils.connectors.ClientTcpConnector.receive(ClientTcpConnector.java:75) [bin/:?]
    at networkUtils.DispatchingManager.run(DispatchingManager.java:37) [bin/:?]
11:48:35.219 [Thread-1] DEBUG networkUtils.connectors.Connector - ClassCastException: 
java.lang.ClassCastException: networkUtils.networkMessage.MessageType cannot be cast to networkUtils.networkMessage.Message
    at networkUtils.connectors.ClientTcpConnector.receive(ClientTcpConnector.java:42) [bin/:?]
    at networkUtils.connectors.ClientTcpConnector.receive(ClientTcpConnector.java:75) [bin/:?]
    at networkUtils.DispatchingManager.run(DispatchingManager.java:37) [bin/:?]

我知道问题出在哪里,但我不知道为什么会这样。 :(

谢谢, 此致

0 个答案:

没有答案