1

我正在使用两个使用套接字进行通信的 java 进程。

从服务器端,我用它来发送信息:

public void send(Serializable order)
{
    try
    {
        if (this.clientSocket != null && this.clientSocket.isBound() && this.clientSocket.isConnected())
        {
            String json = "";
            json = mapper.writeValueAsString(order);
            log.info("sending to client : " + order.getClass());

            json = convertToUTF8(json);

            this.output.write(json + "\n");
            this.output.flush();
            log.info("Message sent to client");
        }
        else
        {
            log.info("no client connected");
        }
    }
    catch (Exception e)
    {
        log.fatal("Exception while trying to send message to client : " + e.getMessage(), e);
    }
}

这里的输出是:

private BufferedWriter output;

在客户端,我尝试读取这样的数据:

while (this.running)
        {   
            try
            {
                String msg = in.readLine();

                log.debug("MSG VALUE IS : |"+msg+"|\n\n**********\n");

                if ("".equalsIgnoreCase(msg) || msg == null)
                {
                    break;
                }

这是一个:

private BufferedReader in;

这里的问题是一段时间后,服务器进程被阻塞,如果我运行 netstat 命令,我可以看到 recv-Q 和 send-Q 的值不为 0。

但我无法重现这种情况,所以我想知道是什么导致了这种情况,有没有办法处理这种情况,还是我必须改变读取数据的方式?

提前致谢。

4

2 回答 2

0

通常,如果您使用来自服务器端代码的阻塞 IO 操作,则每个客户端都需要有自己的工作线程来负责发送到该客户端。

另一种选择是使用 NIO(或一些使用 NIO 的框架)来允许您的服务器多路复用事物。

于 2013-09-25T16:31:14.593 回答
0

为避免阻塞,您应该使用每个请求的广告。

非常简短的例子:

public class App {


    public static void main(String[] args) throws IOException {

        ServerSocket serverSocket = null; // consider it is properly initialized

        while (true /* stub health condition */) {

            Socket clientSocket = serverSocket.accept(); // the blocking call
            final Worker worker = new Worker(clientSocket);

            Thread workerThread = new Thread() {

                @Override
                public void run() {
                    // handle request here
                    worker.send(new Serializable(){} /* stub */);
                }

            };

            workerThread.start();
        }

    }


}

class Worker {

    private Socket clientSocket;

    Worker (Socket clientSocket) {
        this.clientSocket = clientSocket;
    }

    public void send(Serializable order) {
        // logic
    }

}
于 2013-09-25T17:13:01.650 回答