Java 套接字输出延迟了第一条消息

发布于 2024-11-08 23:29:17 字数 1216 浏览 5 评论 0原文

我在 Java 中的套接字方面遇到了一个非常奇怪的问题。这可能是因为我缺乏关于套接字的知识,但事实是:

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

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

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

在此方法的最后,我调用 getOutput().flush();

现在,当我尝试通过我正在编写的客户端向 IRC 服务器发送消息时,似乎需要很长时间才能收到第一条消息。当它最终完成时,一切似乎都进展顺利。所有后续消息都会立即处理。只是我在连接并加入该频道后发送的第一条消息需要很长时间。

我用来向服务器发送消息的方法非常简单:

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

是否有人知道为什么第一条消息需要这么长时间才能传输到服务器,而以下所有消息(在第一条消息最终到达之后)却进展顺利?

如果值得一提的话:我使用 Tomcat6 作为我的 servlet,在其上进行连接,并使用 UnrealIRCd 作为 IRC 服务器。消息通过 AJAX 发送到 servlet。 (但是发送到服务器似乎进展顺利,因为发送消息时我正在执行的 System.out 会立即打印在我的 Tomcat 日志中,因此延迟位于套接字或 IRC 服务器中。 )

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

I'm having a very strange problem with sockets in Java. It could be caused because of my lack of knowledge about sockets but here it is:

I'm using a socket to connect to an IRC-server. The connection is made perfectly and I receive all the messages the IRC-server is sending me.
When the connection is made, I authenticate to the server and I start a seperate thread to receive what the server sends me. In that thread I send a message once when connected to make the program join a certain channel.

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

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

At the end of this method I call getOutput().flush();

Now when I'm trying to send a message TO the IRCserver via the client I'm writing, it seems to take ages before the first message gets through. When it finally get's through everything seems to be working fine. All following messages are handled immediately. It's just that first message I'm sending after being connected and having joined that channel that takes long.

The method I'm using to send a message to the server is very simple:

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

Is there anyone who has a clue why the first message is taking so long to transmit to the server while all the following (after the first finally arrived) go well?

If it might be worth mentioning: I'm using a Tomcat6 for my servlets on which I make the connection and an UnrealIRCd as IRC-server. The messages are send to the servlet via AJAX. (But the sending to the server seems to go well, since the System.out I'm doing when a message is send is printed immediately in my Tomcat-log, so the delay is in the socket OR in the IRC-server..)

If more info is needed, I shall try to provide it, since this might look quite complicated like this..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

葬心 2024-11-15 23:29:17

您的代码似乎每次绕过 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 命令之后,您才能发送 JOIN 命令。已注册,由 001 数字表示,因此您可能需要等待该行后再发送。

请注意,line.contains 并不是一种非常可靠的解析 IRC 消息的方法。如果我向您发送一条包含“JOIN :#prinz”的消息,它也会触发该消息。您应该将每条传入消息分解为源、命令、目标和参数。

Your code appears to send the JOIN commands every time it goes around the while loop, which appears to be once for every line the server sends you, until you finally get the response from the server confirming that you've joined the channel.

This means you'll end up sending those JOIN commands a very large number of times. IRCDs are designed to only handle a set rate of commands per second from each client - so this is probably what's lagging you (your later commands end up on the end of a very long queue filled with lots of JOIN commands).

Instead, you should only send the JOIN commands once only, by setting the flag as soon as you send them:

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;
    }
}

Note that you can't send your JOIN commands until after you're registered, which is indicated by an 001 numeric, so you may need to wait for that line before sending them.

Note that line.contains is not a very robust way of parsing IRC messages. If I send you a message that contained "JOIN :#prinz", it'd trigger on that too. You should be breaking each incoming message up into source, command, destination and arguments.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文