繁体   English   中英

通过TCP套接字的ObjectOutputStream

[英]ObjectOutputStream over a TCP Socket

我使用java.net程序包用Java编写了对等网络游戏,由于某种原因,客户端和服务器之间的套接字关闭或损坏。 我之所以称其为“点对点”,是因为其中一个客户端还运行服务器类,这是我编写的接受套接字连接的自定义类-一个来自另一台计算机,另一个来自客户端计算机。 该连接用于使用ObjectOutputStream和ObjectInputStream来回移动对象。

套接字错误不定期发生。 在出现问题之前,连接通常会打开5-10分钟。 有时它在新游戏开始时关闭,而其他时候在游戏进行时关闭。

  1. 我应该使用keepAlive保持连接打开吗?
  2. 有人对我应该如何解决此问题有建议吗?

这是生成错误的代码:

/**
 * Continually checks for messages to be read in. Then it
 * sends the messages to processMessage if a message is available.
 */
   public void listenForMessages() {
      int availableBytes;
      Object obj = null;
      try {
         availableBytes = socketStream.available();
         if (availableBytes >5) {
            obj = in.readObject();
            message = (ClientMessage) (obj);
            processMessage();
         }
      }
      catch(java.io.StreamCorruptedException utoh) {
          System.out.println("Read failed: " + utoh);
          try {
              System.out.println("Number of Bytes available: " + socketStream.available());
              utoh.printStackTrace();
              System.out.println("Attempting to close socked.");
              socketStream.close();
          }
          catch(IOException ioe) { 
              System.out.println("Unable to close: " + ioe.toString());
          }              
      }
      catch(IOException e) {
         System.out.println("Read failed" + e);
      }

这是错误消息和堆栈跟踪:

Read failed: java.io.StreamCorruptedException: invalid type code: 00
Number of Bytes available: 100

有两个活动套接字(两个流),每个客户端一个。 当另一个套接字抛出相同的错误时,我看到无效的类型代码:FF

堆栈跟踪

java.io.StreamCorruptedException: invalid type code: 00
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1355)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at thornworks.quiz.PlayerInterface.listenForMessages(PlayerInterface.java:227)
at thornworks.quiz.PlayerInterface.actionPerformed(PlayerInterface.java:214)
at javax.swing.Timer.fireActionPerformed(Timer.java:291)
at javax.swing.Timer$DoPostEvent.run(Timer.java:221)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:641)
at java.awt.EventQueue.access$000(EventQueue.java:84)
at java.awt.EventQueue$1.run(EventQueue.java:602)
at java.awt.EventQueue$1.run(EventQueue.java:600)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:611)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

创建网络应用程序时,在开发的早期阶段引入网络I / O日志记录非常重要。 它将帮助您解决简单的错误,例如连接断开以及发送或接收的数据不正确。

我假设您在测试环境中存在连接问题:那是在本地网络上吗? 您能描述一下您的客户吗? 它是移动设备吗?

如果您的应用程序需要持续打开连接,那么我建议您实现一些重新连接逻辑。 也就是说,如果连接断开(在执行I / O操作时检测到连接),则尝试与对等方重新建立连接。

更新:

if (availableBytes >5) {
    obj = in.readObject();
    message = (ClientMessage) (obj);
    processMessage();
}

如果在可用字节中序列化了多个对象,将会发生什么? in.readObject()是什么? 它是否读取对象序列化所需的字节数或所有可用的字节数?

IMO您看到的行为的可能原因是该代码并不希望可以一​​次接收多个对象并将其存储在接收缓冲区中。 同样,接收缓冲区可以包含对象的一部分(例如,object1 + object2的两个字节)。

TCP是一种流协议,因此无法轻松确定消息结束。 您应该实施协议,该协议将确定正在传输的消息的开始和结束。 在你的代码中

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM