如何避免在简单的代理服务器中拒绝连接



我想使用套接字用Java编写一个简单的http代理服务器。我写了一个测试原型,由我在网上找到的几个教程组成。这么久以来,我一直带着这个:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class SimpleProxyServer
{
    public static final int portNumber = 55558;
    public static final int maxConnections = 100;
    public static void main( String[] args )
    {
        SimpleProxyServer proxyServer = new SimpleProxyServer();
        proxyServer.start();
    }
    public void start()
    {
        System.out.println("Starting the SimpleProxyServer ...");
        try
        {
            ServerSocket serverSocket = new ServerSocket( portNumber, maxConnections );
            byte[] buffer = new byte[10000];
            boolean run = true;
            while( run )
            {
                Socket clientSocket = serverSocket.accept();
                InputStream clientInputStream = clientSocket.getInputStream();
                // reading the request and put it into buffer
                final int readBytesCount = clientInputStream.read( buffer );
                if( readBytesCount < 0)
                    continue;
                String browserRequest = new String( buffer, 0, readBytesCount );
                System.out.println( browserRequest );
                // extract the host to connect to
                final int hostNameStart = browserRequest.indexOf( "Host: " ) + 6;
                final int hostNameEnd = browserRequest.indexOf( 'n', hostNameStart );
                final String hostName = browserRequest.substring( hostNameStart, hostNameEnd - 1 );
                System.out.println( "Connecting to host " + hostName );
                // forward the response from the proxy to the server
                Socket hostSocket = new Socket( hostName, 80 );
                OutputStream hostOutputStream = hostSocket.getOutputStream();
                System.out.println( "Forwarding request to server" );
                hostOutputStream.write( buffer, 0, readBytesCount );
                hostOutputStream.flush();
                ProxyThread thread1 = new ProxyThread( clientSocket, hostSocket );
                thread1.start();
                ProxyThread thread2 = new ProxyThread( hostSocket, clientSocket );
                thread2.start();
            }
            serverSocket.close();
        }
        catch( IOException e )
        {
            System.err.println( "IO Error: " + e.getMessage() );
            e.printStackTrace();
        }
    }
}
class ProxyThread extends Thread 
{
    private Socket incoming, outgoing;
    ProxyThread( Socket in, Socket out )
    {
        incoming = in;
        outgoing = out;
    }
    // Overwritten run() method of thread,
    // does the data transfers
    public void run()
    {
        System.out.println( "Starting proxy thread" );
        try
        {
            OutputStream toClient = outgoing.getOutputStream();
            InputStream fromClient = incoming.getInputStream();
            int numberRead = 0;
            byte[] buffer = new byte[10000];
            do
            {
                numberRead = fromClient.read( buffer );
                System.out.println( "Read " + numberRead + " bytes" );
                System.out.println( "Buffer: " + buffer );
                if( numberRead > 0 )
                {
                    toClient.write( buffer, 0, numberRead );
                    System.out.println( "Sent " + numberRead + " bytes" );
                }
            }
            while( numberRead > 0 );
            System.out.println( "Closing all streams and sockets" );
            toClient.flush();
            incoming.close();
            outgoing.close();
        }
        catch( IOException e ) 
        {
            System.err.println( "IO Error: " + e.getMessage() );
        }
        catch( ArrayIndexOutOfBoundsException e )
        {
            System.err.println( "Index error: " + e.getMessage() );
        }
    }
}

在使用浏览器(如果Firefox有帮助的话)进行测试时,它会在fromClient.read(buffer)调用上挂起并冻结很长一段时间,然后返回-1,但浏览器会更早地显示连接拒绝。是什么原因造成的?这是由InputStream.read()阻塞引起的还是有点像比赛?也许整个方法是错误的?或者是线的问题?

p.S.我的"母语"是C++。尽管我偶尔会对Java编程语言有一些经验,但我对它的libs,尤其是套接字,仍然没有足够的经验。

p.p.S.我以为http代理服务器在互联网上有多个教程和操作方法,但我发现的只是单线程或不读取目标URL,只将请求发送给下一个代理。所以,也许这篇帖子会帮助某人写下自己的一篇。如果它被修复了。。。

您必须在一个单独的线程中处理每个接受的套接字,这包括读取CONNECT命令。否则,读取它的阻塞将阻止接受线程接受新的连接。

相关内容

  • 没有找到相关文章

最新更新