When developing socket applications in the past I have sometimes only had accessed to a crippled Internet connection such as college and corporate firewalled networks. This has resulted in my applications having to implement the ability to consume a proxy service like the ones provided in these restricted network environments.
Admittedly I have not yet seen a corporate or college network which provides a SOCKS proxy as these tend to be HTTP proxies but this will be covered in another article. The proxy service I will be consuming in this example will use a tunneled SSH connection with a listening dynamic proxy on port 5000.
In this short tutorial I will walk you through how to enable a Java socket application to consume a SOCKS proxy. The example I will be providing will create a new Proxy instance which consumes our SOCKS proxy listening on localhost port 5000. Once the Proxy instance is created we will then create a Socket instance which uses our Proxy instance to connect to our destination (in our case google.co.uk on port 80).
Please keep in mind that I am not a Java expert and I do not intend to give that impression to readers. My aim is to share information that I have found useful and explain it in a way that others may also find useful. I may have not used 100% correct terminology but if not let me know and I will correct this. Suggestions, comments and questions are always very welcome.
You can download the full source code from here Main.java
Setting up the variables
// Create variables
String proxyHost, destinationHost;
int proxyPort, destinationPort;// Set the proxy host and port we will be using
proxyHost = “localhost”;
proxyPort = 5000;// Set the destination host and port for our socket connection
destinationHost = “google.co.uk”;
destinationPort = 80;
Basically what we have done above is first of all create some empty String and Integer variables to store information regarding the destination host and the proxy we will be connecting through to reach that destination. Now we can go ahead and create the Proxy() instance.
Creating the Proxy() instance
Proxy socksProxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(proxyHost, proxyPort));
What the above does is create a new instance of the Proxy() class named socksProxy. To create the Proxy() instance we must assign it some information so it knows how it should function. First of all we set the type of proxy to SOCKS “Proxy.Type.SOCKS” this tells the Proxy() instance that the type of proxy we shall be consuming is a SOCKS proxy. Next we need to tell out Proxy() instance where our SOCKS proxy is, in our case the proxy is located on the localhost on port 5000 as set previously in the variables proxyHost, proxyPort. The variables proxyHost and proxyPort are now put to use by passing the constructor a secondary argument which is a new instance of InetSocketAddress(). The InetSocketAddress in our example takes the following information “InetSocketAddress(PROXY_SERVER_HOST, PROXY_SERVER_PORT)” replacing PROXY_SERVER_HOST with the proxyHost variable and PROXY_SERVER_PORT with the proxyPort variable.
Connecting to the destination
try {
Socket client = new Socket(socksProxy);
client.connect(new InetSocketAddress(destinationHost, destinationPort));
If you are new to Java and programming in general you may be wondering what the line “try {” actually means. Well it is quite simple, the application will try and execute the code after “try {” and if this is unsuccesful the application will thow an exception. An exception would indicate something unexpected has happened in the application, for example the proxy server is not running. In this case the exception is caught with the “} catch (Exception e) {” statement which we will refer to later on. Lets assume this is a perfect world and nothing went wrong while creating our Socket named client. Our Socket has been created and passed the object we created earlier named “socksProxy” we can now work with the Socket how we usually would when creating a non proxied Socket application. Before we can do anything with “client” we must tell it where we intend to connect to in this case we are connecting to google.co.uk on port 80 so we pass a new instance of “InetSocketAddress” to the connect method.
Input and output streams
BufferedReader inputStream = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter outputStream = new PrintWriter(client.getOutputStream());
As with every Socket connection there is an input and an outputStream. Input being from the server and output being from the client. We create a BufferedReader as the inputStream and a PrintWriter as the outputStream.
Sending commands
outputStream.println(“GET index.html”);
Once the connection and streams are setup we are ready to send some commands to the server. As this is only a basic client we will be sending GET index.html to google.co.uk on port 80. If all goes well then the server should return the HTML content of index.html on the server.
Looping the result
String fromServer = null;
while((fromServer = inputStream.readLine()) != null) {
System.out.println(fromServer);}
client.close();
Once the command GET index.html has been sent we are then ready to get the response from the server. To do this we read the response line by line by using a while loop. For each line we receive from the server this will be printed to the console by the application. Once the command has finished we need to close the connection and can do this by using “client.close();”
Catching exceptions
} catch (Exception e) {
e.printStackTrace();
}
Every exception that can be thrown in Java inherits behavior from the Exception() class. When we throw an exception we can catch everything with Exception even if the Exception happens to be something like IOException or NullPointerException. Once this is caught we can print the output of the exception to the console by using “e.printStackTrace();” where e is the exception as define by “} catch (Exception e) {“