如何在java中执行一个socket之后恢复

mpbci0fu  于 2021-07-06  发布在  Java
关注(0)|答案(0)|浏览(172)

在执行后如何重用套接字时遇到问题。下面是我的密码。

public class SocketUtil {

    private static final String PROTOCAL_TYPE_HTTP = "http";

    private static final String PROTOCAL_TYPE_HTTPS = "https";

    /**
     * create socket
     * @param url
     * @return
     * @throws Exception
     */
    public static Socket connect(URL url) throws Exception {
        String protocal = url.getProtocol();

        Socket socket;
        if(PROTOCAL_TYPE_HTTP.equals(protocal)){
            socket = new Socket();
        } else if(PROTOCAL_TYPE_HTTPS.equals(protocal)){
            SSLContext sslContext = getSslContext();
            socket = sslContext.getSocketFactory().createSocket();
        } else {
            throw new Exception("unsupported protocal");
        }

        InetSocketAddress socketAddress = getSocketAddress(url);

        Integer timeout = 20 * 1000;
        socket.setSoTimeout(timeout);

        socket.setReuseAddress(true);
        socket.setTcpNoDelay(true);
        socket.setKeepAlive(true);
        socket.setSoLinger(true, 1000);

        socket.connect(socketAddress, timeout);

        return socket;
    }

    /**
     * weather a socket is connected or not
     * @param socket
     * @return
     */
    public static boolean isConnected(Socket socket) {
        return socket != null && socket.isBound() && !socket.isClosed() && socket.isConnected()
                && !socket.isInputShutdown() && !socket.isOutputShutdown();
    }

    private static InetSocketAddress getSocketAddress(URL url) throws Exception {
        String protocal = url.getProtocol();

        Integer port = url.getPort();
        if(port == -1){
            if(PROTOCAL_TYPE_HTTP.equalsIgnoreCase(protocal)){
                port = 80;
            } else if(PROTOCAL_TYPE_HTTPS.equalsIgnoreCase(protocal)){
                port = 443;
            } else {
                throw new Exception("unsupported protocal");
            }
        }
        return new InetSocketAddress(InetAddress.getByName(url.getHost()), port);

    }

    /**
     * simple ssl
     * @return
     * @throws Exception
     */
    public static SSLContext getSslContext() throws Exception {

        SSLContext ctx = SSLContext.getInstance("TLS");

        ctx.init(null, new TrustManager[]{getTrustAllManager()}, null);

        return ctx;
    }

    /**
     * trustAll
     * @return
     */
    private static TrustManager getTrustAllManager(){
        X509TrustManager xtm = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws
                    CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

            }
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        return xtm;
    }

}

下面是我的测试

@Test
    public void getTest(){
        try {
            String apiAddress = "http://checkip.amazonaws.com";

            URL url = new URL(apiAddress);
            Socket socket = SocketUtil.connect(url);

            for (int i = 0; i < 5; i++) {
                if(!SocketUtil.isConnected(socket)){
                    System.out.println("reconnect start");
                    socket = SocketUtil.connect(url);
                }

                PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
                printWriter.println("GET /" + url.getFile() + " HTTP/1.0");
                printWriter.println("Host: " + url.getHost());
                printWriter.println("");
                printWriter.flush();

                InputStream ins = socket.getInputStream();
                String resp = IOUtils.toString(ins, "utf8");
                System.out.println(resp);
            }

        } catch (Exception e){
            e.printStackTrace();
        }
    }

如你所见,在我的测试中,我运行了5次执行。在循环中,第一个执行按预期运行,但其他4个执行有点连线,我得到了空白消息。有人知道哪里出了问题,怎么解决吗?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题