0

当我同时连接 500 多个玩家时,我的(多线程)服务器出现了这个奇怪的问题,PrinterWriter 有时需要超过 100 秒或更长时间(2 分钟)才能完成 flush() 或 print()。

这是代码:

public static void send(Player p, String packet)
{   
    PrintWriter out = p.get_out();
    if(out != null && !packet.equals("") && !packet.equals(""+(char)0x00))
    {
        packet = Crypter.toUtf(packet);
        out.print((packet)+(char)0x00);
        out.flush();
    }
}

printWriter 是这样的:

_in = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
_out = new PrintWriter(_socket.getOutputStream());

如果我将关键字 synchronized 添加到 send() 方法,整个服务器开始每 2 秒滞后一次,如果我不这样做,那么一些随机播放器会无缘无故开始滞后。

有人知道吗?这是从哪里来的?我应该怎么办?

4

2 回答 2

1

打印写入器包裹在套接字的输出流周围,所以我猜测并说套接字的输出缓冲区已满,因此 write/flush 调用将阻塞,直到缓冲区有足够的空间容纳正在发送的消息。

如果写入数据的速度快于传输到客户端的速度(或快于客户端接收它的速度),则套接字发送缓冲区可能已满。

编辑:

PS 如果您遇到可伸缩性问题,可能是由于使用 java.io(每个套接字需要一个线程)而不是 java.nio(在这种情况下,单个线程可以检测并在具有待处理数据的套接字上执行操作) )。nio 旨在支持必须扩展到大量连接的应用程序,但编程模型更加困难。

于 2011-07-30T03:42:24.750 回答
0

原因是您的 send() 方法是静态的,因此写入任何套接字的所有线程都在包含的类对象上同步。使其成为非静态的,那么只有写入同一个套接字的线程才会被同步。

于 2011-07-30T03:49:18.517 回答