• Welcome to Overclockers Forums! Join us to reply in threads, receive reduced ads, and to customize your site experience!

Socket communication using Java

Overclockers is supported by our readers. When you click a link to make a purchase, we may earn a commission. Learn More.

RedDragonXXX

Senior RAM Pornographer
Joined
Mar 3, 2005
Location
Jacksonville, FL
I just wanted to see if anyone is familiar with programming Sockets using Java for Client/Server environment. I'm just trying to write a simple program that on the Client side lets user choose form couple of different options then sends that request over a Socket to Server program that processes the request and returns it back to Client. I'm using PrintWriter for output to Client from Server program but it just won't work if I put it inside a conditional statement as so:

Code:
                ServerSocket serverSock = null;
		Socket standSock = null;

	    try
	    {
	    	serverSock = new ServerSocket(7003);
	    	standSock = serverSock.accept();
	    	
	    	InputStreamReader input = new InputStreamReader(standSock.getInputStream());
	    	BufferedReader read = new BufferedReader(input);
	    	PrintWriter print = new PrintWriter(standSock.getOutputStream(), false);
	    	
	    	String dateTime = (Calendar.getInstance()).getTime().toString();

		if (read.readLine().equals("1"))
		{
			System.out.println("Option 1");
			print.println("You're connected to the Server at: " + dateTime);
		}
	    		
	    	System.out.println("Closing Server Connection");
	    	read.close();
	    	input.close();
	    	print.close();
	    	standSock.close();
	       
	    }

The line that I'm talking about is the print.println. I've checked around the web and no one seems to know why this is so wanted to try my luck here :D

Anyways if anyone knows, that would be of great help :thup:
 
Any chance the PrintWriter needs to be flushed to ensure that everything gets sent?
 
Do you get the line System.out.println("Closing Server Connection");?

You don't have anything that will keep reading the PrintWriter your client will be processing the readLine() faster than the server can send it which will complete your program.

You would need to add a while loop

Code:
String currentLine;

while((currentLine = read.readLine()) != null) {
    // Your commands go here


    // Server sends client exit command
    if (currentLine.equals("exit")) {
        break;
    }
}
 
Last edited:
Any chance the PrintWriter needs to be flushed to ensure that everything gets sent?

If you look at the documentation:

http://docs.oracle.com/javase/6/docs/api/java/io/PrintWriter.html

You'll notice that the constructor which takes an Outputstream and boolean uses the boolean to configure auto flush, so your:

Code:
PrintWriter print = new PrintWriter(standSock.getOutputStream(), false);

sets automatic flushing off (you need to flush). You can just remove that boolean setting completely and it should flush automatically.

The reason we are asking if this is executing:

Code:
System.out.println("Option 1");

Is to ensure your evaluation actually works... You don't have a null check and don't trim the input etc.

You could also run:

Code:
if (read.ready())

before reading the input, as that will tell you that the BufferedReader is ready for you.

You can finally check:

Code:
print.checkError()

To verify if there where actual errors while using the PrintWriter.
 
I completely forgot about this thread.

I was able to figure it out. It seems that when you use Socket communication that you can't use output streams in two different places, since you're only getting one output returned. So I just ended up creating a Static Method in my Server program that only returns one String output based on the users choice from the Client program.
 
There is also a lot of reasons you would not want to be passing the socket around... Generally the incoming message would have an id (identifying what it's for) and a payload. You might validate it right a way, then pass the message content on to a handler which handles incoming data for that ID, and can further validate that the content is as expected.

One place will handle the socket, and the message will after validation be used to create a java object that is passed forward as needed. That way if you have a problem there are less places it needs to be fixed in, and only one place that needs to validate the actual message content (you generally should never trust data coming from a client).
 
I ran into another wall. Since the output I'm getting from the Server can sometimes be multiple lines I'm having trouble printing it out all at once on the Client side.

For example it works if I move the user option selection outside the while loop like so:

Code:
System.out.print("Enter your choice: ");
fromClient = stdIn.readLine().trim();

while ((fromServer = input.readLine()) != null)
		{
			System.out.println("Server: " + fromServer);			
			if (fromServer.equals("Bye"))
	 		break;			


			if(fromClient.equals("1"))
			{
				System.out.println("Client: " + fromClient);
				output.println(fromClient);
				
			}
			if(fromClient.equals("2"))
			{
				System.out.println("Client: " + fromClient);
				output.println(fromClient);
				
			}
			if(fromClient.equals("3"))
			{
				System.out.println("Client: " + fromClient);
				output.println(fromClient);
				
			}
			if(fromClient.equals("4"))
			{
				System.out.println("Client: " + fromClient);
				output.println(fromClient);
				break;
				
			}
		

		}

But I need the "Enter your choice: " to keep coming up until user chooses to quit by selection option 4. If I put it inside the loop and server returns multiple line string it print one line then prompts user for their choice, then it prompts second line, asks user for their choice again...

I just need it to finish printing every line then ask user for their choice after.
 
This is really driving me nuts. I've asked around and no one can seem to figure it out. I'm sure it some simple workaround like always that I'm missing :bang head
 
Update

I've figured it out and yes it was a fairly simple workaround like always, it only took 2 days to figure out :bang head

Basically I appended a new line to every String coming from Server side and inside client I've added a condition that only prompts user for their input if last String read length is 0 (which is the new line string :D).
 
if its not a pain could you post a snippet of code to see changes :D

I have no idea whats goin on up there due to my lack of experience but i do enjoy reading and trying to understand
 
if its not a pain could you post a snippet of code to see changes :D

I have no idea whats goin on up there due to my lack of experience but i do enjoy reading and trying to understand

Here is a sample for the server side:

Code:
if (clinetChoice.equals("2"))
		{
			String command = "uptime";

			Process process = Runtime.getRuntime().exec(command);
	
			BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
			
			String line = reader.readLine();
						
			System.out.println("You Chose Option Two");
			output += line + "\n";
		}

if (clinetChoice.equals("3"))
		{
			String command = "free";

			Process process = Runtime.getRuntime().exec(command);
	
			BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
			
			System.out.println("You Chose Option Three");
			
			String line;			

			while ((line = reader.readLine()) != null)
			{
				output += line + "\n";
			}

		}

First if condition works with single lines and as you can see I append new line to the output String at the end. As I mentioned before I do this so that when the client is finished reading the last String it will always be equal to 0 in length because last line is always new line and since there is nothing there its 0.
Second condition works for multiple lines as you can tell by the while loop. This appends new line in order to print each line one by one and also print new line at the end.

Here is client side:

Code:
System.out.print("Enter Your Choice: ");
fromClient = stdIn.readLine().trim();
	
		while ((fromServer = input.readLine()) != null)
		{
			System.out.println("Server: " + fromServer);
			if (fromServer.equals("Bye"))
				break;

			if (fromServer.length() == 0)
			{
				System.out.print("Enter Your Choice: ");
				fromClient = stdIn.readLine().trim();
			}
			if(fromClient.equals("1"))
			{
				System.out.println("Client: " + fromClient);
				output.println(fromClient);
				fromClient = "";
			}

Here I have user make a selection outside loop so that we can get initial value for the fromClient string that gets sent to Server to do something. Based on that selection Server returns appropriate result and while loop runs until end of String/Strings is reached. As you can see I also have a condition inside the loop that prompts for users choice when we are finished displaying result (this can be one line or multiple lines). Without this condition if we were to return a multiple line String from server it would print line one, then ask user for their input, print line two then ask user for their input...

Hope that explains things for you :thup:
 
If it does not seem like too much work for you, I'd change that it so that you cast fromClient to an integer and then do a switch statement with the options and a default case covering an unrecognized input.
 
Yea its all going into a switch statement. When ever I write code I try to get functionality down and then I come back and tidy up the code. I will probably part most of this stuff out into different classes in the end.
 
Back