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

时间:2013-08-19 08:20:04

标签: java nio ioexception apache-httpcomponents synapse

我遇到一个问题,服务器(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”?

1 个答案:

答案 0 :(得分:0)

  

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

你做不到。

  

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

没有

您对ClosedChannelException.有一个基本的误解当已关闭本地频道并继续使用它时,会引发错误。 peer 已关闭连接

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

如果您要查找连接断开或失败的指示,请使用write()抛出IOException: connection reset的情况。