2011-05-22 76 views
1

我在使用Java中的套接字时遇到了一个非常奇怪的问题。这可能是由于我对套接字缺乏了解而造成的,但这里是:Java套接字输出延迟了第一条消息

我使用套接字连接到IRC服务器。连接完美,我收到IRC服务器发给我的所有消息。 进行连接时,我向服务器进行身份验证,然后启动一个单独的线程来接收服务器发送给我的信息。在该线程中,我连接时会发送一条消息,以使程序加入某个通道。

boolean joined = false; 
     while ((line = getInput().readLine()) != null) { 
      if (!joined) { 
       getOutput().println("JOIN #PrinZ"); 
       getOutput().println("JOIN #Trinorae"); 

       if (line.contains("JOIN :#prinz")) { 
        joined = true; 
        System.out.println("JOINED #prinz = true"); 
       } 
      } 

在这个方法的最后我调用了getOutput()。flush();

现在,当我试图通过我正在写的客户端向IRCserver发送消息时,似乎在第一条消息通过之前需要很长时间。当它最终通过一切似乎工作正常。所有以下消息都会立即处理。这只是我在连接并加入该频道之后发送的第一条消息,需要很长时间。

我使用将消息发送到服务器的方法很简单:

public void sendToServer(String input) { 
     getOutput().println(input); 
     getOutput().flush(); 
    } 

是否有任何人谁拥有一个线索,为什么第一条消息是这么长时间来传输到服务器,而所有以下(在第一次终于抵达后)进展顺利吗?

如果它可能值得一提:我使用Tomcat6作为我的servlet,并在其上创建连接,并将UnrealIRCd作为IRC服务器。消息通过AJAX发送到servlet。 (但是发送到服务器似乎进行得很顺利,因为我发送消息时的System.out会立即打印在我的Tomcat日志中,所以延迟在IRC服务器的套接字OR中。 )

如果需要更多的信息,我会尽量提供它,因为这可能看起来很复杂这样的..

+2

如果将flush()移入while循环会发生什么? – MeBigFatGuy 2011-05-22 12:46:18

+0

在while循环中实际上有一个刷新。但是flush是最后的,因为我还做了一些XML解析(将XML发送到客户端)以及两者之间的ping回复。 – StefK 2011-05-22 18:30:32

+0

使用Wireshark监控流量并确定问题是发送延迟还是服务器响应延迟。 – 2011-05-23 02:18:40

回答

0

您的代码似乎每次去各地while循环,时间发送JOIN命令其似乎是服务器向您发送的每一行发送一次,直到您最终从服务器获得确认您已加入该频道的响应。

这意味着您将最终发送这些JOIN命令很多次。 IRCD的设计目的只是为了处理每个客户端每秒钟设定的命令速率 - 所以这可能会滞后于你(后面的命令最终会在很长的队列的末尾填满大量的JOIN命令)。

相反,你应该只有一次只发送了JOIN命令,由只要你给他们设置标志:

boolean sent_join = false; 
boolean joined = false; 

while ((line = getInput().readLine()) != null) { 
    if (!sent_join) { 
     getOutput().println("JOIN #PrinZ"); 
     getOutput().println("JOIN #Trinorae"); 
     sent_join = true; 
    } 

    if (line.contains("JOIN :#prinz")) { 
     System.out.println("JOINED #prinz = true"); 
     joined = true; 
    } 
} 

请注意,你不能把你的JOIN命令,直到你注册后,这是由001数字表示的,因此在发送它们之前您可能需要等待该行。

请注意,line.contains不是解析IRC消息的非常稳健的方式。如果我向您发送包含“JOIN:#prinz”的消息,它也会触发此消息。你应该将每个传入的消息分解为源代码,命令,目的地和参数。

+0

你完全正确的解析。我打算改进它,因为它真的很糟糕。有趣的是,我已经使用了一个更体面的解析来生成我的XML消息。 对于这种导致滞后的坏方法,你可能是对的,这会使第一个真正的消息滞后很多!我会尽力改善这一点,并让你知道它是否已修复! 在此先感谢! – StefK 2011-05-25 07:50:44

+0

好的!我在IRCMessage对象中整齐地分析了一切,将“line.contains(”JOIN #PrinZ“)”改为“if(msg.getCommand()。equals(”001“)&&!joined)”并设置了joined-当我进入时,标志为真如果!看来问题是由这个连接命令产生的延迟导致的。非常感谢caf! – StefK 2011-05-25 09:02:16

+0

@Trinorae:没问题。你真的很幸运,它并没有让你直接从服务器上淹没你 - 如果你连接到一个很长的MOTD的服务器,它可能会使你与“超额洪水”消息断开。 – caf 2011-05-25 10:04:50