Using sockets in Java with a proxy - java

I'm writing a very simple transport simulation (please don't ask why I use this approach, it's not really the point of my question).
I have three threads running (although you could consider them as seperate programs). One as a client, one as a server, and one as a proxy.
The first is used as the client, and the main code for that is given here:
try {
Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(InetAddress.getLocalHost(), 4466));
Socket socket = new Socket(proxy);
InetSocketAddress socketAddress = new InetSocketAddress(InetAddress.getLocalHost(), 4456);
socket.connect(socketAddress);
// send data
for (String straat : straten) {
socket.getOutputStream().write(straat.getBytes());
}
socket.getOutputStream().flush();
socket.getOutputStream().close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
The second is the server side, given here:
public void run() {
try {
ServerSocket ss = new ServerSocket(4456);
Socket s = ss.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(s.getInputStream()));
String incoming;
while ((incoming = in.readLine()) != null) {
panel.append(incoming + "\n");
}
panel.append("\n");
s.getInputStream().close();
s.close();
ss.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
And then there's the proxy-thread:
public void run() {
try {
ServerSocket ss = new ServerSocket(4466);
Socket s = ss.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(s.getInputStream()));
panel.append(verzenderId + "\n");
String incoming;
while ((incoming = in.readLine()) != null) {
panel.append(incoming + "\n");
}
panel.append("\n");
s.getInputStream().close();
s.close();
ss.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
Somehow, this won't work. The message is sent directly to the server, and the proxy doesn't receive any socket request.
How can I make this work so that port 4466 becomes a proxy for the communication between the client-thread and the server-thread?
The goal is to make this socket between the client and the server to become an SSLSocket, so that the proxy can't read anything that goes over it. Therefore, setting up two sockets, one between the client and the proxy and one between the proxy and the server, is not the solution I'm looking for.
Thanks a lot in advance.

Related

Server is not sending back an acknowledgment to Client

I have my server code below over here:
public void startServer() {
ServerSocket listener = selectUnusedPortFromRange(1024, 65535);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
String command = null;
while (true) {
Socket socket = listener.accept();
System.out.println("Got a connection from: " + socket.getLocalPort());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
command = in.readLine();
System.out.println("GOT HERE"); //Not being printed out
if (command != null && !"".equals(command)) {
if ("connection".equals(command)) {
Writer writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write("success\n");
writer.flush();
}
}
}
}
}
}
t.start();
}
This is my client side:
public void makeConnection() {
try {
Socket socket = new Socket(IP, PORT);
Writer writer = new PrintWriter(socket.getOutputStream(), true);
writer.write("connection\n");
BufferedReader socketRead = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str;
while ((str = socketRead.readLine()) != null) {
if ("success".equals(str)) {
System.out.println("Successfully saved all hosts to: " + listOfHosts.get(i));
socketRead.close();
socket.close();
iStream.close();
writer.close();
}
}
}catch (Exception e) {
System.out.println(e.getMessage());
}
}
On the client side after I create my socket to the connect to the server I write "connection" into the outputStream of the socket and wait for an acknowledgement back from the server saying success. For some reason the connection is not being made to the server. In the server System.out.println("Got a connection from: " + socket.getLocalPort()); this line is not being printed out.
Is there something wrong that I am doing. I can't spot it. And I am not getting an exception thrown when I try to connect to my server.
1) Make sure you use the same port for both the Client and Server. They must communicate over the same port. It seems you may be using different ports currently.
2) Make sure you actually start your server thread. As-is in your code above, you make a new Thread, but never start it. t.start() must be called somewhere.
3) If this is on your local machine, you may be better off using localhost instead of the actual IP address. Firewalls might treat your external IP differently.
4) Terminate your messages with a newline character, such as \n, so that your BufferedReader can use it's readLine() method. For good measure, also follow-up by flushing the writer's buffer, just in case the newline character didn't trigger that. writer.flush();
And lastly, make sure you terminate the JVM before trying to run your code again. Your code has not shutdown mechanism to un-bind the server from the port... so you may get an exception thrown telling you the port and/or address are already in use. If that happens, either change ports, or kill the java process running in the background.
Here is your code, slightly modified to run on my system. It's working as you might expect it to. I tried to change as little as possible just to get it working on my system. One note is, I hard-coded the port number into the server and client - that's not required, it was just convenient for me to test with:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
public class Test {
public static void main(String[] args) throws IOException {
Test test = new Test();
test.startServer();
test.makeConnection();
}
public void startServer() throws IOException {
final ServerSocket listener = new ServerSocket(60001);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
String command = null;
while (true) {
Socket socket = listener.accept();
System.out.println("Got a connection from: " + socket.getLocalPort());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
command = in.readLine();
System.out.println("GOT HERE");
if (command != null && !"".equals(command)) {
if ("connection".equals(command)) {
Writer writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write("success\n");
writer.flush();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
t.start();
}
public void makeConnection() {
System.out.println("Making Connection");;
try {
Socket socket = new Socket("localhost", 60001);
Writer writer = new PrintWriter(socket.getOutputStream(), true);
writer.write("connection\n");
writer.flush();
BufferedReader socketRead = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str;
while ((str = socketRead.readLine()) != null) {
if ("success".equals(str)) {
System.out.println("Successfully saved all hosts to: "); //+ listOfHosts.get(i));
socketRead.close();
socket.close();
//iStream.close();
writer.close();
}
}
}catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
I was facing the exact same issue. I overcame it by using an ACK mechanism (Wasn't my idea, it was suggested to me). The idea is that client would make a request to server and keep the socket connection alive (and the ouput stream open) till server responds back an agreed ACK message over the same channel. Once the client receives the ACK message, only then it would close the connection.
Below is the code for Server :-
final ServerSocket listener = new ServerSocket(11111);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
String command = null;
while (true) {
System.out.println("About to accept");
Socket socket = listener.accept();
System.out.println("Got a connection from: " + socket.getLocalPort());
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
StringBuilder str = new StringBuilder(inputStream.readUTF());
//command = in.readLine();
System.out.println("GOT HERE. Msg received : "+str);
if (str != null && !"".equals(str.toString())) {
command = str.toString();
if ("connection".equals(command)) {
System.out.println("Got connection message");
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
outputStream.writeUTF("connection");
outputStream.close();
}
}
inputStream.close();
System.out.println("Done");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
});
t.start();
}
Client :-
public void makeConnection() {
try {
System.out.println("In makeConnection");
Socket socket = new Socket("127.0.0.1", 11111);
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
outputStream.writeUTF("connection");
InputStream inputStream = socket.getInputStream();
DataInputStream dataInputStream = new DataInputStream(inputStream);
StringBuilder str;
do {
str = new StringBuilder(dataInputStream.readUTF());
} while (!str.toString().equals("connection"));
System.out.println("Successfully saved all hosts to: ");
outputStream.close();
dataInputStream.close();
socket.close();
outputStream.close();
}catch (Exception e) {
System.out.println(e.getMessage());
}
}
A call to start the proceedings :-
public void start() throws IOException, InterruptedException {
System.out.println("Starting server");
startServer();
Thread.sleep(1000);
System.out.println("Starting connection");
makeConnection();
}

My Java Server/Client program will only work every third time I run it

I am new to Java Programming, and even newer to Java Networking Programming, so I am sure the problem will be a simple one. My program is based around a submit button which submits the student ID to the server.
The first two times I run the program it will establish a connection with the server and then everything will crash and it will never exchange strings.
However, every third time I run it, it will work perfectly and exchange the strings as designed.
Client:
String currentButton = e.getActionCommand();
if(currentButton == "submit"){
try{
Socket server = new Socket("Localhost",1234);
InetAddress address=InetAddress.getLocalHost();
System.out.println("Connected to "+server.getInetAddress());
System.out.println("Connected to "+address);
BufferedReader br = new BufferedReader(new InputStreamReader(server.getInputStream()));
PrintWriter pw = new PrintWriter(server.getOutputStream(), true);
pw.println(student);
while ((student = br.readLine()) != null) {
System.out.println(student);
pw.println("bye");
if (student.equals("bye"))
break;
}
br.close();
pw.close();
server.close();
} catch (IOException ex){
//ignore exception
}
}
Server
class NETCW1S {
public static void main(String[] args) throws IOException {
String student;
ServerSocket serverSock = null;
InetAddress address=InetAddress.getLocalHost();
try{
serverSock = new ServerSocket(1234);
System.out.println("Waiting for client connection");
} catch (IOException e) {
System.err.println("Could not listen on port: 1234");
System.exit(1);
}
Socket clientSock = null;
try{
clientSock = serverSock.accept();
} catch (IOException e) {
System.err.println("Accept Failed");
System.exit(1);
}
while (true) {
System.out.println("Connected to "+address);
System.out.println("Waiting for client...");
Socket client = serverSock.accept();
System.out.println("Client from "+client.getInetAddress()+" connected.");
Socket fromClientSocket = serverSock.accept();
PrintWriter pw = new PrintWriter(fromClientSocket.getOutputStream(), true);
BufferedReader br = new BufferedReader(new InputStreamReader(fromClientSocket.getInputStream()));
while ((student = br.readLine()) != null) {
System.out.println("The message: " + student);
if (student.equals("bye")) {
pw.println("bye");
break;
} else {
student = "Server returns " + student;
pw.println(student);
}
}
pw.close();
br.close();
fromClientSocket.close();
}
}
Many thanks in advance!
The server should only have one accept() call, inside the loop. The client needs to make a connect() call at some point - right now it doesn't appear to be talking to the client at all.

Java sockets send and receiving data

Hi I am trying to understand how Sockets work can implement a multiplayer side to a monopoly game.I understood how to create the connection, but now it seems I have trouble sending and receiving the data between the client and the server .Here is my code:
Client code:
public class EchoClient
{
public static void main(String[] args)
{
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try
{
echoSocket = new Socket("127.0.0.1", 5000);;
out = new PrintWriter(echoSocket.getOutputStream());
in = new BufferedReader(
new InputStreamReader(echoSocket.getInputStream()));
BufferedReader stdIn = new BufferedReader(
new InputStreamReader(System.in));
String userInput;
while ((userInput = stdIn.readLine()) != null)
{
out.println(userInput);
}
out.close();
in.close();
stdIn.close();
echoSocket.close();
}
catch (UnknownHostException e)
{
System.err.println("Don't know about host: taranis");
}
catch (IOException e)
{
System.err.println("Couldent get I/O for "
+ " the connection to : taranis.");
}
}
}
Server code:
public class ServerSide
{
ServerSocket connect;
Socket connection;
PrintWriter out;
BufferedReader in;
public void go()
{
try
{
connect = new ServerSocket(5000);
connection = connect.accept();
in = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
String userInput;
while ((userInput = in.readLine()) != null)
{
System.out.println("echo: " + in.readLine());
}
}
catch (IOException e)
{
System.out.println(e);
}
}
public static void main(String[] args)
{
new ServerSide().go();
}
}
I was trying to create here a simple connection between a client and a server.On the client side when the user inputs data I want it to be sent to the server and then print it it on the server console.It seems that the way I wright the code it isent working what did I do wrong?
First of all you need to declare a console object and then print on it.
Then don't forget to:
After every print on the console at the server side you need to flush the stream so the all the data will be printed.
Your code looks fine to me. Usually with sockets and keyboard input, you run into the case where the reader.readLine() hangs because it is still trying to read input from the other side. Typically, i will put an empty out.println() at the end of my client so the server will terminate the reading while loop. I've tried flush() before as Mike suggested but that seems to not work for me.
On the client, you're missing out.flush; after the out.println.
On the server,
while ((userInput = in.readLine()) != null) {
System.out.println("echo: " + userInput); // not in.readLine
}

Cannot communicate with server in Java

I am trying to write server to client program but I cannot communicate with the server in Java.
Here is the code block in my main.
InetAddress addr = InetAddress.getLocalHost();
ipAddress = "78.162.206.164";
ServerSocket serverSocket = new ServerSocket(0);
String randomStringForPlayerName = RandomStringGenerator.generateRandomString();
baseForReqOpp += ipAddress + " " + serverSocket + " " + randomStringForPlayerName;
Socket socket = new Socket(host,2050);
socket.setSoTimeout(100);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream());
out.write(baseForReqOpp);
out.flush();
System.out.println(in.read());
I know that there is no problem in the server code and all the communication ports are ok.
But I cannot read anything from the server.
What can be the problem?
you have to create an output stream before the input stream
Here is some working code with communicating client and server sockets. Hopefully you can adapt it for your specific problem.
public class SocketTest {
public void runTest() {
try {
// create the server
new SimpleServer().start();
// connect and send a message
InetAddress addr = InetAddress.getLocalHost();
Socket sock = new Socket(addr, 9090);
ObjectOutputStream out = new ObjectOutputStream(sock.getOutputStream());
out.writeObject("Hello server");
out.flush();
ObjectInputStream in = new ObjectInputStream(sock.getInputStream());
System.out.println("from server: " + in.readObject());
sock.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// server has to run in a separate thread so the code doesn't block
private class SimpleServer extends Thread {
#Override
public void run() {
try {
ServerSocket sock = new ServerSocket(9090);
Socket conn = sock.accept();
// the code blocks here until a client connects to the server
ObjectInputStream in = new ObjectInputStream(conn.getInputStream());
System.out.println("from client: " + in.readObject());
ObjectOutputStream out = new ObjectOutputStream(conn.getOutputStream());
out.writeObject("Hello client");
out.flush();
sock.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
To run it:
new SocketTest().runTest();
Your code will never work because you don't use threads. In order to start the server, you need to call accept at some point in your code
myServerSocket.accept();
this is a blocking call, ie the code flow stops until a client connects. But since you can't execute any statement (remember accept is blocking?) how can a client connect? This chicken and egg problem is resolved through threads. See Howard's answer for a code sample.
I don't see any call to accept(), so I wonder what your client connects to...

Right format to connect to remote tomcat server?

Playing with a few tutorials on sockets but struggling to connect.
My tomcat server is at eric.server.com and is running a ajp connector on port 8052.
I want to use the knock knock java tutorial to connect. I've uploaded the KnockKnockProtocol.class and KnockKnockServer.class to eric.server.com/apps/knock
On the tutorial it shows this:
kkSocket = new Socket("tarranis", 4444);
Which I have changed to:
kkSocket = new Socket("eric.server.com/apps/knock", 8052);
I then run the client program from eclipse but I just get the UnknownHostException.
Could someone please explain what I'm doing wrong, totally new to Tomcat and servlets in general?
TIA
import java.io.;
import java.net.;
public class KnockKnockClient {
public static void main(String[] args) throws IOException {
Socket kkSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
kkSocket = new Socket("eric.server.com", 8052);
out = new PrintWriter(kkSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("Bye."))
break;
fromUser = stdIn.readLine();
if (fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
}
out.close();
in.close();
stdIn.close();
kkSocket.close();
}
}
You are using a host name of "eric.server.com/apps/knock", when what you really want is "eric.server.com".
Then once you have connected, you can then start engaging in the socket's protocol (ajp) to communicate with it. The URI portion goes in the req_uri portion of the protocol, not in the host.
But the bigger issue is that Tomcat is really an HTTP server, not a socket server. You should either write a servlet that implements the server portion of the tutorial and run that in Tomcat, or just write it as a standalone server process.

Categories