0

我有一个服务器(Apache Synapse)间歇性抛出“java.nio.channels.ClosedChannelException”的问题。

java.nio.channels.ClosedChannelException
at sun.nio.ch.SocketChannelImpl.ensureWriteOpen(SocketChannelImpl.java:135)
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:326)
at org.apache.http.impl.nio.reactor.SessionOutputBufferImpl.flush(SessionOutputBufferImpl.java:167)
at org.apache.http.impl.nio.DefaultNHttpServerConnection.produceOutput(DefaultNHttpServerConnection.java:323)
at org.apache.synapse.transport.http.conn.LoggingNHttpServerConnection.produceOutput(LoggingNHttpServerConnection.java:112)
at org.apache.synapse.transport.passthru.ServerIODispatch.onOutputReady(ServerIODispatch.java:87)
at org.apache.synapse.transport.passthru.ServerIODispatch.onOutputReady(ServerIODispatch.java:39)
at org.apache.http.impl.nio.reactor.AbstractIODispatch.outputReady(AbstractIODispatch.java:143)
at org.apache.http.impl.nio.reactor.BaseIOReactor.writable(BaseIOReactor.java:180)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:342)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:316)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:277)
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:105)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:584)
at java.lang.Thread.run(Thread.java:662)

显然服务器试图在一个已经关闭的通道上做一些 IO 操作。我想编写一个客户端程序来随意重现该问题。客户端故意关闭通道导致服务器抛出异常。这是客户端的代码。

public class Client
{
    String hostIp;
    int hostPort;

    public Client(String hostIp, int hostPort) {
        this.hostIp = hostIp;
        this.hostPort = hostPort;
    }

    public void runClient() throws IOException {
        Socket clientSocket = null;
        PrintWriter out = null;
        BufferedReader in = null;

        try {
            clientSocket = new Socket(hostIp, hostPort);
            out = new PrintWriter(clientSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Unknown host: " + hostIp);
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't connect to: " + hostIp);
            System.exit(1);
        }

        String getMessage = "GET /services/echo?wsdl2 HTTP/1.1\n" +
                "Host:localhost\n";

        System.out.println("Client connected to host : " + hostIp + " port: " + hostPort);

        out.println(getMessage);

        in.close();
        out.close();
        clientSocket.close();
    }

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

        Client client = new Client("localhost", 8280);
        client.runClient();
    }
}

当客户端运行时,服务器只是抛出一个 IOException 通知管道已损坏。

java.io.IOException: Broken pipe
    at sun.nio.ch.FileDispatcher.write0(Native Method)
    at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:29)
    at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:69)
    at sun.nio.ch.IOUtil.write(IOUtil.java:40)
    at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:336)
    at org.apache.http.impl.nio.reactor.SessionOutputBufferImpl.flush(SessionOutputBufferImpl.java:100)
    at org.apache.http.impl.nio.DefaultNHttpServerConnection.produceOutput(DefaultNHttpServerConnection.java:220)
    at org.apache.synapse.transport.http.conn.LoggingNHttpServerConnection.produceOutput(LoggingNHttpServerConnection.java:112)
    at org.apache.synapse.transport.passthru.ServerIODispatch.onOutputReady(ServerIODispatch.java:87)
    at org.apache.synapse.transport.passthru.ServerIODispatch.onOutputReady(ServerIODispatch.java:39)
    at org.apache.http.impl.nio.reactor.AbstractIODispatch.outputReady(AbstractIODispatch.java:141)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.writable(BaseIOReactor.java:181)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:346)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:320)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:280)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:106)
    at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:604)
    at java.lang.Thread.run(Thread.java:662)

我应该从客户端做些什么来使服务器抛出“ClosedChannelException”?

4

1 回答 1

0

如何从客户端关闭套接字通道,以便服务器抛出 java.nio.channels.ClosedChannelException

你不能。

我应该从客户端做些什么来使服务器抛出“ClosedChannelException”?

没有什么。

当您关闭本地频道并继续使用它时,您对ClosedChannelException.It is throws有一个基本的误解。不是当连接已被对等方关闭时。

如果您正在寻找流结束指示,请使用read()返回 -1 的情况。

如果您正在寻找连接断开或失败的指示,请使用write()throws的情况IOException: connection reset

于 2013-08-19T10:13:44.580 回答