简单的Java Web代理SocketException:Socket已关闭

时间:2016-03-08 20:43:40

标签: java multithreading sockets proxy

上下文

我正在尝试使用Java构建一个简单的HTTP Web代理。现在我所有的东西都是在端口5041上侦听HTTP请求。现在我有2节课。 Proxy类在端口上打开ServerSocket,我将此套接字称为welcomeSocket。打开此端口后Proxy每次Connection接受新套接字时都会启动一个新的welcomeSocket线程。 Connection类有一些简单的逻辑来读取HTTP请求头信息。稍后将扩展此类以获得进一步的功能。谢谢你的帮助。

问题

当我运行代理并将浏览器配置为指向代理时,我收到SocketException错误,说我的套接字已关闭。我不确定这些是怎么回事。此外,似乎正在创建Connection个线程,但不一定输出HTTP头信息。这很明显,因为输出显示了重复的NEW connection thread created打印,但在打印后没有标题信息。

代理类

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Proxy {
    // Port is 5000 + 41
    private final int PORT;
    private ServerSocket welcomeSocket = null;
    private boolean listening = true;

    public Proxy(int port) {
        PORT = port; 

        try {
            welcomeSocket = new ServerSocket(PORT);
            listenForConnectionRequests();
        } catch (IOException e) {
            System.err.println("There was a problem while creating the welcome socket");
            e.printStackTrace();
            System.exit(-1);
        }
    }

    public void listenForConnectionRequests() {
        System.out.println("Listening for connection requests at " + PORT + "\n");

        while (listening) {
            try {
                new Connection(welcomeSocket.accept()).start();
            } catch (IOException e) {
                System.err.println("I/O error occured while waiting for a connection.");
                e.printStackTrace();
            }
        }
    }
}

连接类

public class Connection extends Thread {
    private Socket connectionSocket = null;
    private ArrayList<String> requestHeaders = new ArrayList<String>();
    private boolean running = true;
    private OutputStream os;
    private InputStream is;

    public Connection(Socket connectionSocket) {
        super("Proxy");
        System.out.println("NEW connection thread created");
        this.connectionSocket = connectionSocket;
    }

    public void run() {
        while (running) {
            readHttpHeader();
        }
    }

    private void stopRunning() {
        running = false;
        System.err.println("Stopping thread.");
        closeEverything();
    }

    private void readHttpHeader() {
        try {
            os = connectionSocket.getOutputStream();
        } catch (IOException e) {
            System.err.println("Problem getting output stream from connection socket.");
            e.printStackTrace();
            stopRunning();
        }

        try {
            is = connectionSocket.getInputStream();
        } catch (IOException e) {
            System.err.println("Problem getting input stream from connection socket.");
            e.printStackTrace();
            stopRunning();
        }

        String input;
        BufferedReader in = null;
        DataOutputStream out = null;
        try {
            in = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
            out = new DataOutputStream(connectionSocket.getOutputStream());

            while ((input = in.readLine()) != null) {
                requestHeaders.add(input);
                System.out.println(input);
            }

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                if (in != null)
                    in.close();
                if (out != null)
                    out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void closeEverything() {
        try {
            connectionSocket.close();
            is.close();
            os.close();
        } catch (IOException e) {
            System.err.println("Problem closing connection or streams");
            e.printStackTrace();
            stopRunning();
        }
    }
}

测试一些网页后的输出

Listening for connection requests at 5041

NEW connection thread created
GET http://127.0.0.1:63342/browserConnection/buildInfo HTTP/1.1
Host: 127.0.0.1:63342
Proxy-Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
Accept: */*
DNT: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8

NEW connection thread created
NEW connection thread created
GET http://google.com/ HTTP/1.1
Host: google.com
Proxy-Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
X-Client-Data: CKK2yQEIwbbJAQj9lcoB
DNT: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: OGP=-5061574:; SID=DQAAAMoCAACmU0EuiAZrQAuo8mgssp5cukiLvNn13ryGL2GeGswaF8Cmv2NIxyW_nnC7ihLpQRaY0gdlYg4K91TStT2aPHo3PWFhExCr5zD0yywqgMwsXuWgQedtdi8Lc6tsL0Nz2WSt8j1Is6Dw53SYpWw-Ukis9d386YATJRYdsDUhVsb3h-pe-QrKNBL3deaxIlMIb5itaAWVTSVkRUVcocns6S-mAopRFT-k8YMKXKVeouztBQhblI1YQUKAtMCqv55ZllmFyfZSQcqmbcsJx19ofBLnl6u2KByIwBLwMMa1DrK1YketAgvgxUzlrfanvTm94VQ7Lie9rppG-up1cNlDsu4XbXrIOkG2bdbD7J2SdjwmI_Hf9IrLl3IelDvdCfQol3CT8rdAMk1p7zBMQq5L_JfiiCLmjNd9VA0CiadcB-6dIBWnGGThNYEOkrU11i2qeiEPtvJqDx_7kyuphkFuQh8b5GI7f5xg-uVmLfjaO4Q7q5EiV7BTt5jacajRibvPsqK77lEw9_UTnPvXOkW1jmfJOKx85rAztVpV2vymO_dGMiG_ehiD4R6CO6ifCnHjij5TKUeWeSEzQdtdDsKGL3MAMSg1bZVKcmc3Veq77AwWZa996gUkyEdD1dJ5c4eTodTEjTx8KiUDEufPGxQtjyOEuT8rnY_MWvDTFUx0os-aMZfcYsLrTmJ6mWpYzKa5wnCvFHKnjBL24UddbBmhhaklLcOghJEH8kcVEVWvNuKC145OIzxwZA2CmTCfEDzymOd6pTGlwl9P7VInl2ro_SkoNmEn6VqUWLRC0zH1jEWZhpkNf9kbpLmWBS-xLWMBpvgPu7ysVBf7qR8_YlzyVprCdRDAR4mrciRaOaswHvWCWgU8EJk_gF8PgiP_D2WEtw8uJR6b4IL_ggxpmckGdHM7yUvkel9jWeFQxrazmF1f1c6SHBooSO6t-tCW7-Hw44A; HSID=A_KCc1Le4o6JlU760; APISID=hE0OzriLy98RcM4M/ALgi7Gky2rmmyyiDE; NID=77=dmymZT8yk5KfHAaIyzxhzvKfG_fvBjPwDpg-yTfz_5cBDKAsqL9n010br6xg1dSRrSKhS--_RYLoCuDodOzAHiaWS11pBB-4Npc9eQbqwkLnaf-nzeqNC_fwNSDElB7qfUmmvnZSHX1mowllXfpIM8cLm-ewYD0tGdHbpfvbAxkfH_jIwQKj-pS0f6ZkcodJ2CEEeoDhMUbZDAOfBKUUhM5qvLxE3curLhef6pftojQo0QpTumhoky2_pWR1lWP-5W0lPN29lMDSdeYrW5Umz_3jNHPRyMiGFwzNMIV9r9RUoyO50JreK057mDnzNygESvk_fBHlt49b2U6tesQ5NAtaAmL4VaWsAuj3jKEvjWTxSgSVrUeWwPC84hjn3liuGlBulWg; OGPC=5061900-22:5061918-27:5061934-15:5061921-40:5061937-46:5061933-25:5061941-6:5061574-1:5061940-57:5061952-26:5061975-14:5061983-7:

Problem getting output stream from connection socket.
java.net.SocketException: Socket is closed
    at java.net.Socket.getOutputStream(Socket.java:916)
    at Connection.readHttpHeader(Connection.java:46)
    at Connection.run(Connection.java:34)
Stopping thread.
Problem getting input stream from connection socket.
java.net.SocketException: Socket is closed
    at java.net.Socket.getInputStream(Socket.java:876)
    at Connection.readHttpHeader(Connection.java:54)
    at Connection.run(Connection.java:34)
Stopping thread.
java.net.SocketException: Socket is closed
    at java.net.Socket.getInputStream(Socket.java:876)
    at Connection.readHttpHeader(Connection.java:65)
    at Connection.run(Connection.java:34)
Problem getting output stream from connection socket.
java.net.SocketException: Socket is closed
    at java.net.Socket.getOutputStream(Socket.java:916)
    at Connection.readHttpHeader(Connection.java:46)
    at Connection.run(Connection.java:34)
Stopping thread.
Problem getting input stream from connection socket.
java.net.SocketException: Socket is closed
    at java.net.Socket.getInputStream(Socket.java:876)
    at Connection.readHttpHeader(Connection.java:54)
    at Connection.run(Connection.java:34)
Stopping thread.
java.net.SocketException: Socket is closed
    at java.net.Socket.getInputStream(Socket.java:876)
    at Connection.readHttpHeader(Connection.java:65)
    at Connection.run(Connection.java:34)
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
GET http://www.yelp.com/ HTTP/1.1
Host: www.yelp.com
Proxy-Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
DNT: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: __cfduid=dd3ccfb39916d84ca8053ba95c0ca89fe1457229239; yuv=pOdmTZnrxWdr1NhFcLyF8cCB7Pj5l2tN3CSqNp0fiz0yKun0fbD0MHFrIo4K432S0pKC_-Sl9QijvKAX5u1iUJMmwZ2EnL4p; hl=en_US; fd=0; D_SID=172.250.60.189:SscPaGXtn/I/Skx3ISxQZOtF5qtsm+TmywEwnqXsiuo; qntcst=D%2CT%2C43606%2C43604%2C43602%2C43597%2C43596%2C43595%2C43583%2C43582%2C43581%2C37336%2C34588%2C34585%2C27425%2C27424%2C20052%2C20047%2C20040%2C20021%2C20020%2C20015%2C19991%2C19989%2C19958%2C19948%2C19947%2C19945%2C19944%2C19942%2C19941%2C19939%2C19936%2C19934%2C19932; __qca=P0-1476739725-1457229248633; fbm_97534753161=base_domain=.yelp.com; location=%7B%22city%22%3A+%22Seattle%22%2C+%22zip%22%3A+%22%22%2C+%22country%22%3A+%22US%22%2C+%22address2%22%3A+%22%22%2C+%22address3%22%3A+%22%22%2C+%22state%22%3A+%22WA%22%2C+%22address1%22%3A+%22%22%2C+%22unformatted%22%3A+%22seattle%22%7D; bse=b955bbc7020253479a51b278e343d766; __utma=165223479.439363298.1457229244.1457383227.1457394139.4; __utmc=165223479; __utmz=165223479.1457383227.3.3.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); __utmv=165223479.|4=account%20level=anon=1; _ga=GA1.2.C1BEB9B4D17FEEDD; D_PID=469F0452-18FF-3E05-8072-566D9785BE96; D_IID=EC337894-ADD2-36A6-848D-AA87DA4B1407; D_UID=6E67A9C8-F999-33A6-8838-4EBFBC9B943E; D_HID=qXtXeOzvXZDnGT33GPaUewyWk7KgXdgunNy1mqdkX7g

Problem getting output stream from connection socket.
Problem getting output stream from connection socket.
Problem getting output stream from connection socket.
Problem getting output stream from connection socket.

1 个答案:

答案 0 :(得分:2)

您正在关闭套接字,然后尝试从中读取。

以下代码将调用readHttpHeader两次...

while (running) {
    readHttpHeader();
}

第一次成功:

try {
    in = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));

    while ((input = in.readLine()) != null) {
        requestHeaders.add(input);
        System.out.println(input);
    }

然后关闭输入流......

} finally {
    try {
        if (in != null)
            in.close();

关闭它包装的流(InputStreamReader),然后关闭套接字的输入流。

然后你循环第二次调用readHttpHeader(),它发现流已关闭。几个try-catch块捕获一些错误,将它们报告给stderr,然后混淆,到达读取循环(失败),最后关闭流。最后,由于runningfalse,因此readHttpHeader()不会被第三次调用。