2012-03-08 86 views
0

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

插座错误不规则发生。出现问题前,连接通常会打开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) 
+1

难以回答无码问题。 – vulkanino 2012-03-08 15:51:37

+0

“套接字错误发生不规则”:*什么*'套接字错误'?把它贴在这里,用堆栈跟踪。 – EJP 2012-03-09 00:15:38

+0

我发布了一些代码和堆栈跟踪。希望有所帮助。 – Thorn 2012-03-09 15:48:31

回答

1

当创建网络应用程序是非常重要的,以在年初推出的网络I/O记录发展。它将帮助您解决简单的错误,如连接中断和发送或接收的错误数据。

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

如果应用程序需要连接不断地开放,我会建议实施一些重新连接逻辑。即如果连接中断(您在执行I/O操作时检测到它),则尝试与对等端重新建立连接。

UPDATE:

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

是否有可用的字节序列化的几个对象,会发生什么? 什么是in.readObject()?它是否为对象序列化或可用的所有内容读取所需的字节数量?

IMO你看到的行为的原因可能是代码不指望几个对象可以同时接收并存储在接收缓冲区。接收缓冲区也可以包含部分对象(例如object1 + object2的两个字节)。

TCP是一个流协议,因此不能容易地确定消息结束。您应该实施协议,以确定正在传输的消息的开始和结束。 在您的代码中

+0

我几年前编写了这个程序,当时我第一次学习Java,最近又刚刚学习了它。你的日志建议非常好,现在我肯定会做,但不是10年前。测试环境是本地网络,两个客户端都是运行Java 6的Windows PC。 – Thorn 2012-03-09 00:21:52