Java Echo Server - java

Hello guys I am trying to do an echo Server by java but it is nnot working .. .I don't know why .. but it seems like the server is waiting the client and the client is waiting the server ... so they can't deliver the infromation to each other ..
here is the code
for the Server
ServerSocket server = null;
try {
server = new ServerSocket(3333);
System.out.println("Listening on 3333");
} catch (IOException ex) {
System.out.println("Error can't connect to 3333");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = server.accept();
} catch (IOException ex) {
System.out.println("Accept fail");
System.exit(1);
}
PrintWriter out = null;
try {
out = new PrintWriter(clientSocket.getOutputStream());
} catch (IOException ex) {
Logger.getLogger(JavaApplication20.class.getName()).log(Level.SEVERE, null, ex);
}
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (IOException ex) {
Logger.getLogger(JavaApplication20.class.getName()).log(Level.SEVERE, null, ex);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String inputLine, outputLine;
while(!(inputLine=br.readLine()).equals("bye"))
{
out.print("echo: " + inputLine);
}
out.close();
br.close();
clientSocket.close();
server.close();
System.out.println("Server Exited");
and here is the code for the client
Socket client = null;
try {
client = new Socket("localhost", 3333);
System.out.println("Connected on 3333");
} catch (UnknownHostException ex) {
System.out.println("Couldn't connect to the server");
System.exit(1);
} catch (IOException ex) {
Logger.getLogger(KnockKnockClient.class.getName()).log(Level.SEVERE, null, ex);
}
PrintWriter out = null;
BufferedReader in = null;
BufferedReader stdIn = null;
try {
out = new PrintWriter(client.getOutputStream(), true);
} catch (IOException ex) {
Logger.getLogger(KnockKnockClient.class.getName()).log(Level.SEVERE, null, ex);
}
try {
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
} catch (IOException ex) {
Logger.getLogger(KnockKnockClient.class.getName()).log(Level.SEVERE, null, ex);
}
stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer, fromUser;
while((fromUser=stdIn.readLine())!=null)
{
System.out.println("From user: "+ fromUser);
out.print(fromUser);
fromServer=in.readLine();
System.out.println(fromServer);
}
out.close();
stdIn.close();
in.close();
client.close();
System.out.println("client Exited");
Any Help with that ??

You're sending some string from the client ("Hello" for example), and you're trying to read it with readLine() on the server (and vice versa). readLine() will only return once it finds an EOL character, or once the input stream is closed.
Since the client doesn't send any EOL char, the server waits indefinitely, and the client also because it waits for the answer from the server.
Send "Hello\n", and it will work better.

After out.print(fromUser); use out.flush() in your client and server. flush will make sure it will right to the socket.
while((fromUser=stdIn.readLine())!=null)
{
System.out.println("From user: "+ fromUser);
out.print(fromUser);
out.flush();
fromServer=in.readLine();
System.out.println(fromServer);
}
out.close();
stdIn.close();
in.close();
client.close();
Regarding flush, Extracted from java doc.
Flushes the stream. If the stream has saved any characters from the various write() methods in a buffer, write them immediately to their intended destination. Then, if that destination is another character or byte stream, flush it. Thus one flush() invocation will flush all the buffers in a chain of Writers and OutputStreams.
If the intended destination of this stream is an abstraction provided by the underlying operating system, for example a file, then flushing the stream guarantees only that bytes previously written to the stream are passed to the operating system for writing; it does not guarantee that they are actually written to a physical device such as a disk drive.

Related

Server doesn't receive message in client-server application

In my client-server application, the client sends message to Server and the Server should display the message. But in my case, the client is only able to send but the server can't achieve it.
I have tried with different port numbers (i.e. 8080, 8000, 4444 etc). It seems that the socket can set up the connection, but I really don't know why the server can't read the input from client.
This is my complete project (I have ignored the main classes for both application here, because I have nothing more than just calling the methods):
EchoServer.java:
package client.server;
import java.io.*;
import java.net.*;
public class EchoServer {
public EchoServer() {
}
public void establish() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(8080);
} catch (IOException e) {
System.out.println("Could not listen on port: 1234");
System.exit(-1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.out.println("Accept failed: 1234");
System.exit(-1);
}
PrintWriter out = null;
BufferedReader in = null;
try {
out = new PrintWriter(
clientSocket.getOutputStream(), true);
in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
} catch (IOException ioe) {
System.out.println("Failed in creating streams");
System.exit(-1);
}
String inputLine, outputLine;
try {
while ((inputLine = in.readLine()) != null) {
out.println(inputLine);
if (inputLine.equals("Bye.")) {
break;
}
}
} catch (IOException ioe) {
System.out.println("Failed in reading, writing");
System.exit(-1);
}
try {
clientSocket.close();
serverSocket.close();
} catch (IOException e) {
System.out.println("Could not close");
System.exit(-1);
}
}
}
EchoClient.java:
package server.client;
import java.io.*;
import java.net.*;
public class EchoClient {
public EchoClient() {
}
public void establish() {
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
//echoSocket = new Socket(InetAddress.getLocalHost(), 1234);
echoSocket = new Socket(InetAddress.getLocalHost(), 8080);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
echoSocket.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");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(
new InputStreamReader(System.in));
String userInput;
try {
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
if (userInput.equals("Bye.")) {
break;
}
System.out.println("echo: " + in.readLine());
}
out.close();
in.close();
stdIn.close();
echoSocket.close();
} catch (IOException ioe) {
System.out.println("Failed");
System.exit(
-1);
}
}
}
Your server doesn't write the incoming text to the console but only back to the client which doesn't handle incoming text from the server yet.
(out isn't System.out but Socket.out!)
In your server you are listening with readLine() in whileloop
while ((inputLine = in.readLine()) != null) {
System.out.println("inputLine "+inputLine);
which is nothing but the inputstream from client. The above SOP will print the message from client. Try to flush your streams because it won't print until your buffer is full.
Code seems to be fine. If you write some thing on PrintWriter at both server & client ends, you will get output.
Add below code in server: ( After creating Socket with accept() API)
out.println("Hello from Server");
Add below code in client ( After creating Socket)
out.println("Hello from client");
Other suggestions:
1) Create a thread once you accept a Socket Connection at server and that thread should handle all IO processing
2) You can create thread at client end too after creating Socket with Server. The new thread should handle all IO processing

Java and sockets, the code doesn´t continue

I am not an expert in this, but the code code below just prints message "Waiting for connection.....", and doesn´t print other messages. Why? There is no exception and the thread is running, but after calling accept() method, it doesn´t continue.
public static void main(String[] args) {
try {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(0);//0 any free port
} catch (IOException e) {
System.err.println("Could not listen on port: xxx.");
System.exit(1);
}
Socket clientSocket = null;
System.out.println("Waiting for connection.....");
// try {
clientSocket = serverSocket.accept();
/* } catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}*/
//And now there is no output, "Waiting for connection....." is the last one
System.out.println("Connection successful");
System.out.println("Waiting for input.....");
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("Server: " + inputLine);
out.println(inputLine);
if (inputLine.equals("Bye.")) {
break;
}
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
} catch (IOException ex) {
Logger.getLogger(Sockets.class.getName()).log(Level.SEVERE, null, ex);
}
}
The code works for me, provided I updated the code to tell me port to connect my client to. Try changing the waiting message to:
System.out.println("Waiting for connection on port " + serverSocket.getLocalPort() + ".....");
and then connecting to that port using telnet:
telnet localhost <port number>
I got it echoing my input back just fine.
You could pass in the desired port as a command line parameter, rather than simply picking an arbitrary one.

Java socket receives byte array where each byte is 0

I am making a program which takes a file, and sends it via socket to client. Client receives it and saves it to a file. That is what it is supposed to do.
But somehow, byte array which client receives, contains only 0 bytes, so my output file is empty. here is the code:
Server:
try {
serverSocket=new ServerSocket(7575);
serverSocket.setSoTimeout(1000000);
System.out.println("serverSocket created.");
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Error in creating new serverSocket on port 7575");
}
for(int i=0;i<array.length;i++)
System.out.println(array[i]);
Socket socket=null;
try {
System.out.println("Waiting for client...");
socket=serverSocket.accept();
System.out.println("Client accepted.");
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
PrintWriter outWriter=null;
DataOutputStream outputStream=null;
OutputStream os=null;
BufferedOutputStream bos=null;
try {
os=socket.getOutputStream();
outputStream=new DataOutputStream(os);
outWriter=new PrintWriter(socket.getOutputStream());
bos=new BufferedOutputStream(socket.getOutputStream());
System.out.println("Server streams created.");
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("sending name "+name);
outWriter.println(name);
outWriter.flush();
outWriter.println(array.length);
outWriter.println("array.length"+array.length);
outWriter.flush();
try {
os.write(array);
os.flush();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("couldnt send array of bytes");
}
try {
os.close();
outputStream.close();
socket.close();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
client:
public class Client implements Runnable {
private Socket socket;
private String folderPath;
public Client(String p)
{
folderPath=p;
}
#Override
public void run()
{
try {
System.out.println("Client connecting to localhost on 7575 port...");
socket=new Socket("localhost", 7575);
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
BufferedReader reader=null;
BufferedInputStream bis=null;
InputStream input=null;
DataInputStream in=null;
try {
System.out.println("creating streams");
reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
input=socket.getInputStream();
in=new DataInputStream(input);
bis=new BufferedInputStream(socket.getInputStream());
System.out.println("streams created!");
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
String name="";
int size=0;
String s="32";
try {
name=reader.readLine();
s=reader.readLine();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
if(s!=null)
size=Integer.parseInt(s);
System.out.println("name: "+name);
System.out.println("size: "+size);
byte [] arr=new byte[size];
try {
input.read(arr);
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("couldnt read the byte array");
}
for(int i=0;i<arr.length;i++)
System.out.println(arr[i]);
FileOutputStream fos=null;
try {
fos=new FileOutputStream(folderPath+"/"+name);
} catch (FileNotFoundException ex) {
System.out.println("Could write the file");
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
try {
fos.write(arr);
fos.flush();
} catch (IOException ex) {
System.out.println("Could write the file2");
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
try {
fos.close();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
try {
in.close();
input.close();
reader.close();
socket.close();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Mixing binary and text modes on the same stream is tricky. You would be advised not to do it. Using DataInputStream (for the name, count and file content) is one possible solution. (And that is what I would try). Another would be to encode the file content as text (e.g. using Base64 encoding).
The problem with your current "mixed stream: code is on the client side. When you read the name and size from the BufferedReader, you will cause the reader to read and buffer up to 4096 bytes from the socket. The problem is that some of those bytes are file content. So when you then try to read the content from the underlying InputStream here:
input.read(arr);
you may find that there is nothing left to read. Result: an empty or corrupted file.
There's another problem too. Your code assumes that the input.read(arr) statement is going to read the rest of the stream, or until it fills the byte array. This assumption is incorrect. When you are reading from a socket stream, the read is liable to return only the bytes that are currently available (in the client-side network stack).
Once again, the result is liable to be a corrupted file. (In this case truncated.)
The read code should look something like this:
int count = 0;
while (count < size) {
int bytesRead = is.read(bytes, count, bytes.length - count);
if (bytesRead == -1) {
throw EOFException("didn't get a complete file");
}
count += bytesRead;
}
Finally:
Reading the file content into byte arrays at both ends wastes memory, and is going to be problematic for a really large file.
You really should be using "try with resources" to ensure that the streams are all closed properly. Doing it by hand is cumbersome, and risks resource leaks.
you can use DataOutputStream to directly write some string(message) on output stream using writeUTF() function. And then u can receive your message using object of DataInputStream class by using readUTF() method.
u can send data using following:-
String message="something";
DataOutputStream out=new DataOutputStream(socket.getOutputStream());
out.writeUTF(message);
and u can receive data or message using following:-
DataInputStream in=new DataInputStream(socket.getInputStream());
String message=in.readUTF();
i basically used these method to read data from input stream and write data to outputstream many times and it worked every time, so u should check this way too.
I am making a program which takes a file, and sends it via socket to client. Client receives it and saves it to a file. That is what it is supposed to do.
If you have no need to inspect the content of what is being passed through, then straight InputStream and OutputStream are the way to go, in my opinion. The code is straightforward and fast as it avoids any overhead imposed by higher-level stream types that inspect the content for encoding, etc. This also reduces the opportunity for corrupting the information.
I agree with Stephen C's answer except for
Reading the file content into byte arrays at both ends wastes memory, and is going to be problematic for a really large file.
With the specific requirement to simply move one file to another system with no need to look at the values, this isn't an issue if you know how to handle the content. The basic flow is
client: InputStream in = getFileInputStream();
OutputStream out = socket.getOutputStream();
byte[] bytes = new byte[BUFFER_SIZE]; // could be anything
int bytesRead;
while((bytesRead = in.read(bytes)) != -1){
out.write(bytes,0,bytesRead);
}
in.close();
out.close();
server: InputStream in = socket.getInputStream();
OutputStream out = getFileOutputStream();
// the rest is the exact same thing as the client
This will handle any arbitrarily sized file, limited only by disk size of the server.
Here is an example I whipped up. It's admittedly hacky (the use of the FILE_COUNTER and STOP_KEY for example) but I'm only attempting to show various aspects of having a user enter a file and then send it between a client and server.
public class FileSenderDemo {
private static final int PORT = 7999;
private static final String STOP_KEY = "server.stop";
private static final int[] FILE_COUNTER = {0};
public static void main(String[] args) {
FileSenderDemo sender = new FileSenderDemo();
Thread client = new Thread(sender.getClient());
Thread server = new Thread(sender.getServer());
server.start();
client.start();
try {
server.join();
client.join();
} catch (InterruptedException e) {
FILE_COUNTER[0] = 999 ;
System.setProperty(STOP_KEY,"stop");
throw new IllegalStateException(e);
}
}
public void send(File f, OutputStream out) throws IOException{
try(BufferedInputStream in = new BufferedInputStream(new FileInputStream(f),1<<11)){
byte[] bytes = new byte[1<<11];
int bytesRead;
while((bytesRead = in.read(bytes)) != -1){
out.write(bytes,0,bytesRead);
}
}
}
public Runnable getClient() {
return () -> {
while(FILE_COUNTER[0] < 3 && System.getProperty(STOP_KEY) == null) {
Socket socket;
try {
socket = new Socket("localhost", PORT);
} catch (IOException e) {
throw new IllegalStateException("CLIENT: Can't create the client: " + e.getMessage(), e);
}
File f = getFile();
try (BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream())) {
send(f, out);
} catch (IOException e) {
System.out.println("CLIENT: Failed to send file " + f.getAbsolutePath()+" due to: " + e.getMessage());
e.printStackTrace(System.err);
} finally {
FILE_COUNTER[0]++;
}
}
System.setProperty(STOP_KEY,"stop");
};
}
public File getFile(){
Scanner scanner = new Scanner(System.in);
System.out.println("CLIENT: Enter a file Name: ");
return new File(scanner.next());
}
public Runnable getServer(){
return () -> {
OutputStream out = null;
try{
ServerSocket server = new ServerSocket(PORT);
server.setSoTimeout(20000);
while(System.getProperty(STOP_KEY) == null){
Socket socket = null;
try {
socket = server.accept();
}catch (SocketTimeoutException e){
System.out.println("SERVER: Waited 20 seconds for an accept. Now checking if we need to stop.");
continue;
}
String fileName = "receivedFile_"+System.currentTimeMillis()+".content";
File outFile = new File(fileName);
out = new BufferedOutputStream(new FileOutputStream(outFile));
InputStream in = socket.getInputStream();
int bytesRead;
byte[] bytes = new byte[1<<12];
while((bytesRead = in.read(bytes)) != -1){
out.write(bytes,0,bytesRead);
}
out.close();
socket.close();
System.out.println("SERVER: Just created a new file: " + outFile.getAbsolutePath());
}
System.out.println("SERVER: " + STOP_KEY + " was not null, so quit.");
}catch (IOException e){
throw new IllegalStateException("SERVER: failed to receive the file content",e);
}finally {
if(out != null){
try{out.close();}catch (IOException e){}
}
}
};
}
}

Connecting to multiple sockets from one client

Hi I am new to java client server programming, and I have this modification of a simple program. What I am trying to do is create 2 sockets within the same client, which I then want to use to access 2 sockets on 2 different servers.
The server responds with a very simple String, which is then written into a file and displayed to console. This works fine for whichever sockets code I put first. i.e. if i put clientsocket1 code on top, it receives correctly, but clientsocket2 doesn't get anything.
Vice versa if I flip the order.
Im testing it all on my own computer so I'm using default IP address "0.0.0.0" and different port numbers for the servers.
What could be the issue here?
public static class CustomerClient extends Thread {
private Socket clientSocket1;
private Socket clientSocket2;
String serverInput1;
String serverInput2;
String clientCustomerId;
public CustomerClient(String customerId, String IPAdress1,
int portNumber1, String IPAdress2, int portNumber2) {
try {
clientCustomerId = customerId;
clientSocket1 = new Socket(IPAdress1, portNumber1);
clientSocket2 = new Socket(IPAdress2, portNumber2);
}
catch (UnknownHostException ex) {
System.out.println("connection error " + ex);
} catch (IOException ex) {
System.out.println("Some other exception" + ex);
} catch (Exception ex) {
System.out.println("Some other final exception" + ex);
}
}
public void run() {
try {
DataOutputStream outToServer = new DataOutputStream(
clientSocket1.getOutputStream());
BufferedReader inFromServer = new BufferedReader(
new InputStreamReader(clientSocket1.getInputStream()));
while ((serverInput1 = inFromServer.readLine()) != null) {
BufferedWriter br = new BufferedWriter(new FileWriter(
tempFile, true));
br.write(serverInput1);
br.newLine();
// br.append(modifiedSentence);
System.out.println("FROM SERVER: " + serverInput1);
br.close();
}
DataOutputStream outToServer2 = new DataOutputStream(
clientSocket2.getOutputStream());
BufferedReader inFromServer2 = new BufferedReader(
new InputStreamReader(clientSocket2.getInputStream()));
while ((serverInput2 = inFromServer2.readLine()) != null) {
BufferedWriter br = new BufferedWriter(new FileWriter(
tempFile, true));
br.write(serverInput2);
br.newLine();
// br.append(modifiedSentence);
System.out.println("FROM SERVER: " + serverInput2);
br.close();
}
} catch (IOException ex) {
} catch (Exception e) {
System.out.println("Error" + e);
} finally {
try {
clientSocket1.close();
clientSocket2.close();
} catch (Exception e) {
System.out.println("Error in closing the connection" + e);
}
}
}
}
Isn't, in your case, the client also a server? Because a normal client only connects to one server and that server can handle multiple clients. So, if you want your client to have multiple "connections" to your server, you have two possibilities:
Make your client a server itself by giving it a ServerSocket object or
Create a kind of protocol, which serializes data in this connection and distributes it correctly

Sockets, BufferedReader.readline() - why the stream is not ready?

i'm learning java and i faced some problems with sockets. I developed a simple client-server app - kind of knock-knock, it performs 4 steps:
client sends some message to server
server recieves them and saves to file
server sends back to client some other messages
client recieves them and also saves to file
Problem appears on step #4: client doesn't recieve messages and never gets out the loop:
while ((inStr = in.readLine()) != null) {
writer.println(inStr);
}
where in is type of BufferedReader:
try {
socket = new Socket(ipAddress, 4444);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
On server side messages are sent:
try {
socket = srvSocket.accept();
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
...
out.println("test from server #1");
out.println("test from server #2");
on client side i watched in.ready() - it returns false. On server side i watch out.checkError() - it returns true;
What am i doing wrong - why is the stream empty ?
Any help ia appreciated! :)
You are using public PrintWriter(OutputStream out, boolean autoFlush) which will flush automatically on new line or println. It does not autoflush after every write. You have to flush after every write.
Here is javadoc for the autoFlush param of the constructor:
A boolean; if true, the println, printf, or format methods will flush the output buffer
This might/might not solve your problem. But try keeping everything within Try Catch block. For eg: your ServerSocket initialization, writer blocks etc. If some error occurs, you might not be able to use writer anyhow, so there is no point in initializing it.
You might try writing to standard output stream for debugging instead of a file. Below code for Server/ Client is a minor variant of yours and its working.
Server:
Socket socket;
ServerSocket srvSocket;
BufferedReader in;
PrintWriter out;
try {
srvSocket=new ServerSocket(4444);
socket = srvSocket.accept();
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.println("test from server #1");
out.println("test from server #2");
} catch (IOException e) {
e.printStackTrace();
}
Client
Socket socket;
BufferedReader in;
PrintWriter out;
String inStr;
try {
socket = new Socket("127.0.0.1", 4444);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while ((inStr = in.readLine()) != null) {
System.out.println(inStr);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

Categories

Resources