Simple Java client and server not interacting properly - java

I can't understand why the code below doesn't work. The client sends a message to the server, and the server prints the message to standard output.
Code for the server:
import java.net.*;
import java.io.*;
import java.math.BigInteger;
public class server
{
public static void main(String args[])
{
try
{
ServerSocket server = new ServerSocket(8080);
while (true)
{
// initializations
Socket connection = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
PrintWriter out = new PrintWriter(connection.getOutputStream());
// listen for client message
String message = in.readLine();
// print raw message from client
System.out.println(message);
// close resources
if (out != null)
out.close();
if (in != null)
in.close();
if (connection != null)
connection.close();
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
System.exit(1);
}
}
}
Code for the client:
import java.net.*;
import java.io.*;
import java.math.BigInteger;
public class client
{
public static void main(String args[])
{
try
{
// initializations
Socket connection = new Socket("localhost", 8080);
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
PrintWriter out = new PrintWriter(connection.getOutputStream());
// send message to server
out.println("Hello, world!");
// close resources
if (in != null)
in.close();
if (out != null)
out.close();
if (connection != null)
connection.close();
}
catch (Exception e)
{
System.out.println(e.getMessage());
System.exit(1);
}
}
}
Any insights? Thanks!

What you should be doing to figure out this type of problem, is to isolate where the problem comes from. Is it the Server portion, or the client portion? An easy test for the server is to start it up, then telnet to that port (ex. "telnet 127.0.0.1 8080") type in something and see if it is outputing. (btw, your server code works fine).
Doing this would allow you to focus on your client code. As Affe stated, you simply didn't flush out the input stream. Learning methodologies for troubleshooting code is at least as important as learning to write code.
Also as an aside, by convention, Java classes start with a capital letter, so it should be "Server" and "Client"

That default PrintWriter does not autoflush. (and doesnot flush on close as abstract Writer deceptively may lead you to believe. Either do:
PrintWriter out = new PrintWriter(connection.getOutputStream(), true);
or else
out.println("Hello, world!");
out.flush();

Add a flush after you write to the stream in your client :
// send message to server
out.println("Hello, world!");
out.flush();
Also Make sure the server socket is not blocked by firewall

Related

Reading Object sent by me from Server Java

Hello I am trying to send an object to a server, and then after the server has received it, taking that same object from the server and reading it as a String in the client output. My initial sent message seems to work while everything after that isnt, here is my code:
import java.io.*;
import java.net.*;
public class GUGLi {
static Socket socket = null;
static ObjectOutputStream out = null;
static ObjectInputStream in = null;
String host = "host";
public static void main(String[] args) throws IOException {
try {
OpenPort();
InfoSent();
ReadInfo();
String line;
while ((line = in.toString()) != null) {
System.out.println(line);
}
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + "host");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for "
+ "the connection to: " + "host");
System.exit(1);
in.close();
socket.close();
out.close();
}
}
public static void OpenPort() throws UnknownHostException, IOException{
socket = new Socket ("host", 7879);
}
public static void InfoSent()throws IOException {
Student info = new Student (22, "Guglielmo", "Male",
"email", "#");
out = new ObjectOutputStream(socket.getOutputStream());
out.writeObject(info);
System.out.println("Sent: " + info);
out.flush();
}
public static void ReadInfo()throws IOException {
in = new ObjectInputStream(socket.getInputStream());
}
}
line = in.toString() doesn't read lines. It turns an InputStream into its string representation. You need to invoke a read method. If you are hoping to read lines you need BufferedInputStream.readLine(). But if you're reading objects over the same socket you can't mix stream/reader types, so you should read with readUTF() and write with writeUTF() at the other end.
The first problem you have is you're not calling a reading method as sais by #EJP, so see his answer to have more details.
EDIT: I've deleted the information about not being able to receive data in your InputStream. I was wrong about thinking that your socket was not connected to another client, cause i was thinking that String host = "host" would connect to the loopback address, and I was not seeing any code to send data back to your InputStream.
I suggest that you read some tutorials to clear that out. I suggest you Java tutorial about socket to have a strong basic. It will explain everything you need.

Getting Null String when reading from a socket

I am trying to write a client-server system using Sockets in java, however I cannot seem to read data sent from the server to the client.
Here is the code for the client:
public class ClientSocket
{
Socket clientSocket = null;
PrintWriter out = null;
BufferedReader in = null;
// establish a connection to All Care's server application through socket 4444 (adjust localhost to reflect the IP address that the server
// is being run from)
public ClientSocket()
{
try
{
clientSocket = new Socket("localhost", 4445);
out = new PrintWriter(clientSocket.getOutputStream());
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}
catch (IOException e)
{
System.out.println("Could not connect to All Care Server Application");
}
}
public void closeClientSocket()
{
try
{
clientSocket.close();
}
catch (IOException e)
{
System.out.println("Could not close connection to All Care Server Application");
}
}
public String getMessageFromServer()
{
try
{
String input = in.readLine();
return input;
}
catch (IOException e)
{
System.out.println("Could not read message from server");
}
return "No Data";
}
public void sendMessageToServer(String message)
{
out.write(message);
}
}
And here is the Server code:
public class ArFileServer {
public static void main(String[] args)
{
ServerSocket serverSocket = null;
boolean listening = true;
try
{
serverSocket = new ServerSocket(4445);
// infinite loop to continually listen for connection requests made by clients
while (listening)
{
new ClientConnection(serverSocket.accept()).start();
if (serverSocket != null)
{
System.out.println("Connection to client established");
}
}
serverSocket.close();
}
catch (IOException e)
{
System.out.println("Error could not create socket connection to port");
}
}
}
public class ClientConnection extends Thread
{
private Socket socket = null;
public ClientConnection(Socket socket)
{
super("ClientConnection");
this.socket = socket;
}
// the thread that runs after a connection to the server has been accepted
#Override
public void run()
{
try
{
PrintWriter out = new PrintWriter(socket.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
sendMessagetoClient(out, "CONNECTION SUCCESS");
// check login credentials sent from client to the server
// if valid send back their encrypted password, otherwise output a login error message
// wait for user input and then do various processes based on their requests
in.close();
out.close();
socket.close();
}
catch (IOException e)
{
System.out.println("Client socket connection error");
}
}
// sends a message to the client
void sendMessagetoClient(PrintWriter out, String message)
{
out.write(message);
}
// listens for a message from the client
String getMessageFromClient(BufferedReader in)
{
try
{
String input = in.readLine();
return input;
}
catch (IOException e)
{
System.out.println("Could not read message from client");
}
return "No Data";
}
And here is the line of code im using to see if the data is being sent.
System.out.println(clientSocket.getMessageFromServer());
In your sendMessageToClient() method, you need to flush:
void sendMessagetoClient(PrintWriter out, String message)
{
out.write(message);
out.flush();
}
Or, when you create the PrintWriter, use the constructor with autoflush:
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
And when you write, instead of out.write(message) use printf() or println().
There are several problems here.
You are reading lines but you aren't writing lines.
You aren't checking the result of readLine() for null, which means the peer has closed the connection, which means you must do likewise.
You aren't flushing the PrintWriter after you write.
You are closing things in the wrong order. You must close the output writer/stream you have attached to the socket. Doing that flushes it and then closes the input stream/reader and the socket. Doing this in the wrong order loses the flush. Once you've closed the output you don't need the other two closes.
You are using PrintWriter, which swallows exceptions, across a network, where you need to know about exceptions and errors in communication, and you aren't checking for errors either. Use a BufferedWriter.
in the clint code you are not connecting with server socket.
for clint socket connection
socket soc= new socket ("server host ip",port);

Is it possible to run a socket server and socket client on the same machine?

In java it is possible to create a socket server and a socket client, is it possible to have an instance of the socket server running and a socket/server client that is receiving data from the socket server on the same machine?
e.g the socket server runs on port 60010
and the socket client is running on the same machine connecting to that port through a socket or will I need to by a new machine and add it to my network? If it has a unique IP Address and port number running on the TCP/IP layer.
Here's a simple runnable example to get you started. It starts two threads, one with a ServerSocket and one which makes a Socket connection. One continuously sends strings and the other prints them.
You should simply be able to run this class as-is.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
public class SocketTest {
public static void main(String[] args) throws IOException {
startServer();
startSender();
}
public static void startSender() {
(new Thread() {
#Override
public void run() {
try {
Socket s = new Socket("localhost", 60010);
BufferedWriter out = new BufferedWriter(
new OutputStreamWriter(s.getOutputStream()));
while (true) {
out.write("Hello World!");
out.newLine();
out.flush();
Thread.sleep(200);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
public static void startServer() {
(new Thread() {
#Override
public void run() {
ServerSocket ss;
try {
ss = new ServerSocket(60010);
Socket s = ss.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(s.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
Yes, you can have the following on the same machine:
ServerSocket server = new ServerSocket(60010);
Socket client = server.accept();
Somewhere else:
Socket socket = new Socket("localhost", 60010);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println("Hello server");
Yes, you can run a client and server on the same machine. I do it all the time for development. If you are having troubles though, some routers have problems forwarding packets back to themselves. Try using localhost instead of your external IP for development.
Yes it is completely possible. Every OS has a loopback interface. You can have multiple clients connect to one server on your computer. This kind of communication takes place over the loopback interface.

Communication via standard input / output in Java

I am trying to send messages between two JVMs: a server starts a second process. The second process is then to send a message to the server which prints the message to the console. The code is as follows:
public class Server
{
public static void main(String[] args)
{
Process client=null;
BufferedReader clientInput=null;
try
{
client=Runtime.getRuntime().exec("java Client");
clientInput=new BufferedReader(new InputStreamReader(client.getInputStream()));
}
catch(IOException e){}
System.out.println("Waiting for the client to connect...");
try
{
String msg=clientInput.readLine();
System.out.println(msg);
}
catch(IOException e){}
client.destroy();
}
}
and
public class Client
{
public static void main(String[] args)
{
BufferedWriter out = new BufferedWriter( new OutputStreamWriter(System.out));
try
{
out.write("Ready\n");
out.flush();
}
catch (Exception e){}
}
}
If I run this, I get as output from the server null. In the end, the communication should be both ways. Any help greatly appreciated.
EDIT: I don't get any errors (just removed the print statements from the catch blocks to save space).
I think you need to add a while loop:
while ((s = in.readLine()) != null && s.length() != 0)
System.out.println(s);
}
You receive null at the end of the stream. The client correctly starts, sends Ready, and the the ends, so the stream ends.
Totally correct behaviour. If the client would end itself (but instead do something else like reading server messages on stdin), the server would never receive a null.
Edit: NEVER EVER (!!!!!) do this:
catch(IOException e){}
At least write:
catch(IOException e){ e.printStackTrace() }
This will show you your error!
In my company, this is one of the elementary rules of code style!

Listen to port via a Java socket

A server software my client communicates with regularly sends transaction messages on port 4000. I need to print those messages to the console line by line. (Eventually I will have to write those values to a table, but I’m saving that for later.)
I tried this code but it doesn’t output anything:
package merchanttransaction;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.ClassNotFoundException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class MerchantTransaction {
public static void main(String[] args) {
try {
InetAddress host = InetAddress.getLocalHost();
Socket socket = new Socket("192.168.1.104", 4000);
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
String message = (String) ois.readObject();
System.out.println("Message: " + message);
ois.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
By the way, I need to be able to monitor that port until the program terminates. I’m not sure if the code above will be able to do that because I don’t see any iteration to the code.
I’m using Java version 1.6.0_24, SE Runtime Environment (build 1.6.0_24-b07) running on Ubuntu.
You need to use a ServerSocket. You can find an explanation here.
What do you actually want to achieve? What your code does is it tries to connect to a server located at 192.168.1.104:4000. Is this the address of a server that sends the messages (because this looks like a client-side code)? If I run fake server locally:
$ nc -l 4000
...and change socket address to localhost:4000, it will work and try to read something from nc-created server.
What you probably want is to create a ServerSocket and listen on it:
ServerSocket serverSocket = new ServerSocket(4000);
Socket socket = serverSocket.accept();
The second line will block until some other piece of software connects to your machine on port 4000. Then you can read from the returned socket. Look at this tutorial, this is actually a very broad topic (threading, protocols...)
Try this piece of code, rather than ObjectInputStream.
BufferedReader in = new BufferedReader (new InputStreamReader (socket.getInputStream ()));
while (true)
{
String cominginText = "";
try
{
cominginText = in.readLine ();
System.out.println (cominginText);
}
catch (IOException e)
{
//error ("System: " + "Connection to server lost!");
System.exit (1);
break;
}
}

Categories