⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cproxy.java

📁 java环境下完整的sock4/sock5包装类
💻 JAVA
字号:
/*************************************************************************
 FILE :		  CProxy.java

 Author :	  Svetoslav Tchekanov  (swetoslav@iname.com)

 Description: CProxy class definition.

			  CProxy.class is the implementation of TCP Proxy server


 Copyright notice:
	Written by Svetoslav Tchekanov (swetoslav@iname.com)
	Copyright(c) 2000

This code may be used in compiled form in any way you desire. This
file may be redistributed unmodified by any means PROVIDING it is 
not sold for profit without the authors written consent, and 
providing that this notice and the authors name is included. If 
the source code in this file is used in any commercial application 
then a simple email would be nice.

This file is provided "as is" with no expressed or implied warranty.
The author accepts no liability if it causes any damage to your
computer.

*************************************************************************/


package	socksshttp;

///////////////////////////////////////////////

import	java.io.*;
import	java.net.*;

///////////////////////////////////////////////

public class CProxy	implements	Runnable
{
	protected	Object	m_lock;
	
	public static final int	DEFAULT_BUF_SIZE = 4096;
	
	protected	Thread		m_TheThread	= null;
	
	protected	CServer			m_SocksServer	= null;
	public	CServer	getSocksServer()	{	return m_SocksServer;	}
	
	public	Socket			m_ClientSocket	= null;
	public	Socket			m_ServerSocket	= null;
	
	public	int				m_BufLen		= DEFAULT_BUF_SIZE;
	public	byte[]			m_Buffer		= null;
	
	public	InputStream		m_ClientInput	= null;
	public	OutputStream	m_ClientOutput	= null;
	public	InputStream		m_ServerInput	= null;
	public	OutputStream	m_ServerOutput	= null;
	
	public static final int DEFAULT_TIMEOUT	= 10;
	
	protected	boolean	m_bUseSHttpProxy	= false;
	protected	String	m_cProxyHost		= null;
	protected	int		m_nProxyPort		= 0;
	
	public	boolean	doUseSHttpProxy(){	return	m_bUseSHttpProxy;	}
	public	int		getProxyPort()	{	return	m_nProxyPort;	}
	public	String	getProxyHost()	{	return	m_cProxyHost; 	}

	///////////////////////////////////////////////
	
	public	CProxy( CServer SocksServer, Socket ClientSocket )
	{
		m_lock = this;
		
		m_SocksServer = SocksServer;
		if( m_SocksServer == null )	{
			Close();
			return;
		}
		
		m_ClientSocket = ClientSocket;
		if( m_ClientSocket != null )	{
			try	{
				m_ClientSocket.setSoTimeout( DEFAULT_TIMEOUT );
			}
			catch( SocketException e )	{
				Log.Error( "Socket Exception during seting Timeout." );
			}
		}
		m_bUseSHttpProxy= m_SocksServer.m_bUseSHttpProxy;
		m_cProxyHost	= m_SocksServer.m_cProxyHost;
		m_nProxyPort	= m_SocksServer.m_nProxyPort;
		
		m_Buffer = new byte[ m_BufLen ];
		
		Log.Println( "Proxy Created." );
	}
	
	///////////////////////////////////////////////
	
	public	void	SetLock( Object lock )
	{
		this.m_lock = lock;
	}
	
	
	///////////////////////////////////////////////

	public	void	start()
	{
		m_TheThread = new Thread( this );
		m_TheThread.start();
		Log.Println( "Proxy Started." );
	}
	/////////////////////////////////////////////////////////////

	public	void	stop()	{
	
		try	{
			if( m_ClientSocket != null )	m_ClientSocket.close();
			if( m_ServerSocket  != null )	m_ServerSocket.close();
		}
		catch( IOException e )	{
		}
		
		m_ClientSocket = null;
		m_ServerSocket  = null;
		
		Log.Println( "Proxy Stopped." );
		
		m_TheThread.stop();
	}
	
	/////////////////////////////////////////////////////////////
//	Common part of the server

	public	void	run()
	{
		SetLock( this );
		
		if( ! PrepareClient() )	{
			Log.Error( "Proxy - client socket is null !" );
			return;
		}

		ProcessRelay();

		Close();
	}
	///////////////////////////////////////////////
	///////////////////////////////////////////////

	public	void	Close()		{
		try	{
			if( m_ClientOutput != null )	{
				m_ClientOutput.flush();
				m_ClientOutput.close();
			}
		}
		catch( IOException e )	{
		}
		try	{
			if( m_ServerOutput != null )	{
				m_ServerOutput.flush();
				m_ServerOutput.close();
			}
		}
		catch( IOException e )	{
		}
		
		try	{
			if( m_ClientSocket != null )	{
					m_ClientSocket.close();
				}
			}
			catch( IOException e )	{
		}
		
		try	{
			if( m_ServerSocket != null )	{
					m_ServerSocket.close();
				}
			}
			catch( IOException e )	{
		}
		
		m_ServerSocket = null;
		m_ClientSocket = null;
		
		Log.Println( "Proxy Closed." );
	}
	///////////////////////////////////////////////
	///////////////////////////////////////////////
	
	public	void	SendToClient( byte[] Buf )	{
		
		SendToClient( Buf, Buf.length );
	}
	//--------------
	public	void	SendToClient( byte[] Buf, int Len )	{
		if( m_ClientOutput == null )		return;
		if( Len <= 0 || Len > Buf.length )	return;
		
		try	{
			m_ClientOutput.write( Buf, 0, Len );
			m_ClientOutput.flush();
		}
		catch( IOException e )	{
			Log.Error( "Sending data to client" );
		}
	}
	///////////////////////////////////////////////
	
	public	void	SendToServer( byte[] Buf )	{
		
		SendToServer( Buf, Buf.length );
	}
	//----------------
	public	void	SendToServer( byte[] Buf, int Len )	{
		if( m_ServerOutput == null )		return;
		if( Len <= 0 || Len > Buf.length )	return;
		
		try	{
			m_ServerOutput.write( Buf, 0, Len );
			m_ServerOutput.flush();
		}
		catch( IOException e )	{
			Log.Error( "Sending data to server" );
		}
	}
	
	///////////////////////////////////////////////
	
	public	boolean	isActive()	{
		return	(m_ClientSocket != null && m_ServerSocket != null);	
	}
	
	///////////////////////////////////////////////
	///////////////////////////////////////////////
	
	public	void	ConnectToServer( String Server, int port ) 
		throws IOException, UnknownHostException
	{
	//	Connect to the Remote Host
		
		if( Server.equals("") )	{
			Close();
			Log.Error( "Invalid Remote Host Name - Empty String !!!" );
			return;
		}
		
		if( m_bUseSHttpProxy )	{
			Server = m_cProxyHost;
			port   = m_nProxyPort;
		}
		
		m_ServerSocket = new Socket( Server, port );
		m_ServerSocket.setSoTimeout( DEFAULT_TIMEOUT );
		
		Log.Println( "Connected to "+Log.getSocketInfo( m_ServerSocket ) );
		PrepareServer();
	}
	/////////////////////////////////////////////////////////////
	protected	void	PrepareServer()	throws IOException	{
	synchronized( m_lock )
	{
		m_ServerInput  = m_ServerSocket.getInputStream();
		m_ServerOutput = m_ServerSocket.getOutputStream();
	}
	}
	/////////////////////////////////////////////////////////////
	
	public	boolean	PrepareClient()	{
		if( m_ClientSocket == null )	return false;

		try	{
			m_ClientInput = m_ClientSocket.getInputStream();
			m_ClientOutput= m_ClientSocket.getOutputStream();
		}
		catch( IOException e )	{
			Log.Error( "Proxy - can't get I/O streams!" );
			Log.Error( e );
			return	false;
		}
		return	true;
	}

	///////////////////////////////////////////////
	
	static	final	byte	SOCKS5_Version	= 0x05;
	static	final	byte	SOCKS4_Version	= 0x04;

	CSocks4	comm = null;
	
	public	void	ProcessRelay()	{
		
		try	{
			byte	SOCKS_Version	= GetByteFromClient();
			
			switch( SOCKS_Version )	{
			case SOCKS4_Version:	comm = new CSocks4( this );
									break;
			case SOCKS5_Version:	comm = new CSocks5( this );	
									break;
			default:	Log.Error( "Invalid SOKCS version : "+SOCKS_Version );
						return;
			}
			Log.Println( "Accepted SOCKS "+SOCKS_Version+" Request." );
						
			comm.Authenticate( SOCKS_Version );
			comm.GetClientCommand();
			
			switch ( comm.Command )	{
			case CSocks4.SC_CONNECT	:	comm.Connect();
										if( doUseSHttpProxy() )	{
											CreateSSLTunnel();
										}
										Relay();
										break;
			
			case CSocks4.SC_BIND	:	comm.Bind();
										Relay();
										break;
			
			case CSocks4.SC_UDP		:	comm.UDP();
										break;
			}
		}
		catch( Exception   e )	{
			Log.Error( e );
		}
	} // ProcessRelay
	
	/////////////////////////////////////////////////////////////

	public	byte	GetByteFromClient()
		throws Exception
	{
		int	b;
		
		while( m_ClientSocket != null )		{
			
			try	{
				b = m_ClientInput.read();
			}
			catch( InterruptedIOException e )		{
				Thread.yield();
				continue;
			}
						
			return (byte)b; // return loaded byte
	
		} // while...
		throw	new Exception( "Interrupted Reading GetByteFromClient()");
	} // GetByteFromClient()...
	///////////////////////////////////////////////
	
	///////////////////////////////////////////////
	
	public	static	final	String	EOL = "\r\n";
	
	///////////////////////////////////////////////
	
	public	void	CreateSSLTunnel()
		throws	Exception
	{
		Log.Println( "Initiating SSL Tunneling..." );
		
		String	Host = comm.m_ServerIP.getHostAddress();
		String	cmd = "CONNECT "+Host+":"+comm.m_nServerPort+
					  " HTTP/1.0"+EOL+EOL;

		SendToServer( cmd.getBytes() );
		
		// Wait for Proxy Reply...
		int	dlen = 0;
		while( dlen == 0 )	{
			try	{
				dlen = m_ServerInput.read( m_Buffer, 0, m_BufLen );
				if( dlen > 0 )	{
					String	s = new String( m_Buffer, 0, dlen );
					if( s.startsWith( "HTTP/1.0 200" ) ||
						s.startsWith( "HTTP/1.1 200" ) )
					{
						Log.Println( "SHTTP Proxy Reply : [Connection Established]" );
					}
					else	{
						Log.Println( "SHTTP Proxy Reply : ["+s.trim()+"]" );
						throw new Exception("Error Response from SHTTP Proxy !");
					}
				}
			}
			catch( InterruptedIOException e )	{
				dlen = 0;
			}
		}// While...
	}
	///////////////////////////////////////////////
	
	public	void	Relay()	{
	
		boolean	Active		= true;
		int		dlen		= 0;

		while( Active )	{
			
		//---> Check for client data <---
			
			dlen = CheckClientData();
			
			if( dlen < 0 )	Active = false;
			if( dlen > 0 )	{
				LogClientData( dlen );
				SendToServer( m_Buffer, dlen );
			}
			
			//---> Check for Server data <---
			dlen = CheckServerData();
			
			if( dlen < 0 )	Active = false;
			if( dlen > 0 )	{
				LogServerData( dlen );
				SendToClient( m_Buffer, dlen );
			}
			
			Thread.currentThread().yield();
		}	// while
	}
	
	/////////////////////////////////////////////////////////////

	public	int		CheckClientData()	{
	synchronized( m_lock )
	{
	//	The client side is not opened.
		if( m_ClientInput == null )	return -1;

		int	dlen = 0;

		try
		{
			dlen = m_ClientInput.read( m_Buffer, 0, m_BufLen );
		}
		catch( InterruptedIOException e )		{
			return	0;
		}
		catch( IOException e )		{
			Log.Println( "Client connection Closed!" );
			Close();	//	Close the server on this exception
			return -1;
		}

		if( dlen < 0 )	Close();

		return	dlen;
	}
	}
	///////////////////////////////////////////////
	/////////////////////////////////////////////////////////////

	public	int		CheckServerData()	{
	synchronized( m_lock )
	{
	//	The client side is not opened.
		if( m_ServerInput == null )	return -1;

		int	dlen = 0;

		try
		{
			dlen = m_ServerInput.read( m_Buffer, 0, m_BufLen );
		}
		catch( InterruptedIOException e )		{
			return	0;
		}
		catch( IOException e )		{
			Log.Println( "Server connection Closed!" );
			Close();	//	Close the server on this exception
			return -1;
		}

		if( dlen < 0 )	Close();

		return	dlen;
	}
	}
	///////////////////////////////////////////////

	///////////////////////////////////////////////
	
	public	void	LogServerData( int traffic )	{
		Log.Println("Srv data : "+
					Log.getSocketInfo( m_ClientSocket ) +
					" << <"+
					comm.m_ServerIP.getHostName()+"/"+
					comm.m_ServerIP.getHostAddress()+":"+
					comm.m_nServerPort+"> : " + 
					traffic +" bytes." );
	}
	
	///////////////////////////////////////////////
	
	public	void	LogClientData( int traffic )	{
		Log.Println("Cli data : "+
					Log.getSocketInfo( m_ClientSocket ) +
					" >> <"+
					comm.m_ServerIP.getHostName()+"/"+
					comm.m_ServerIP.getHostAddress()+":"+
					comm.m_nServerPort+"> : " + 
					traffic +" bytes." );
	}
	
	///////////////////////////////////////////////
}
///////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -