I've been trying to write a client process that will communicate with a serve.
I used the same code below but instead of scanner i used BufferedReader and the client input was a string. Furthermore, the server just changes the string to uppercase and sends it back to the client to be displayed on the screen. It worked.
However, when i changed the code so that the client can enter a double number [(ex: 1.6) the server should round it and send it back so that it'll be printed on the screen], i get no response.
And i got this error:
run:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextDouble(Scanner.java:2413)
at socketserver.SocketServer.main(SocketServer.java:38)
Java Result: 1
notes:
I am using NetBeans.
I used Scanner instead of using BufferedReader so that i'll be able to read a double number.
Client class
package socketclient;
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class SocketClient {
/**
* #param args the command line arguments
*/
public static void main(String args[]) throws Exception
{
double inputDouble;
double modifiedNum;
Scanner inFromUser = new Scanner(System.in);
Socket clientSocket = new Socket("localhost", 6789);
DataOutputStream outToServer =
new DataOutputStream(clientSocket.getOutputStream());
Scanner inFromServer = new Scanner(clientSocket.getInputStream());
inputDouble = inFromUser.nextDouble();
outToServer.writeDouble(inputDouble);
modifiedNum = inFromServer.nextDouble();
System.out.println("FROM SERVER: " + modifiedNum);
outToServer.close();
clientSocket.close();
}
}
Server class
package socketserver;
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class SocketServer {
/**
* #param args the command line arguments
*/
public static void main(String args[]) throws Exception
{
double clientNum;
double roundedNum;
ServerSocket welcomeSocket = new ServerSocket(6789);
while(true) {
Socket connectionSocket = welcomeSocket.accept();
Scanner inFromClient = new Scanner(connectionSocket.getInputStream());
DataOutputStream outToClient =
new DataOutputStream(connectionSocket.getOutputStream());
clientNum = inFromClient.nextDouble();
roundedNum= Math.round(clientNum);
outToClient.writeDouble(roundedNum);
}
}
}
Your error is to use Scanner to read data sent by client from the server and the converse.
You use DataOutputStream to sent a double so you need a DataInputStream to read the double; on both sides.
Change your Scanners to DataInputStream for inputFromServer and inputFromClient. Also don't forget to flush your outputs and close the streams at the end.
Related
I'm practising WebSocket in java and wrote two simple programs which one of them is a server that starts listening in port 9090 and receives a string as input from the client then makes a string uppercase and returns back to the client.
The program has no error but for some reason, it does not work. I can't find out what is the problem.
After debuting it seems like the server doesn't receive the inputs string even though both sides connect to each other successfully. When the user inputs his/her string the client sends it to the server but the server doesn't receive it, therefore, both programs go to the wanting stage and the application will not respond.
could you please help me with the issue?
Thanks in advance
server-side code :
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
public static void main(String[] args) throws IOException {
// Start listening at port 9090
ServerSocket s = new ServerSocket(9090);
System.out.println("Started: " + s);
Socket socket = s.accept();
System.out.println("conecction accepted by " + socket);
try {
// Buffer reader to get input and save it as "in"
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()
)
);
// write the output as "out"
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()
)
));
// A Loop for waiting to receive the input from the client
while (true) {
System.out.println("Watting for inpute line ...");
String line = in.readLine();
// print the input string to console to make sure it recive the input
System.out.println("inputed Line: " + line);
// sent back upper case string to client
out.println(line.toUpperCase());
out.flush();
}
}finally {
System.out.println("closing...");
socket.close();
}
}
}
The cline side code:
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
// get the Address for localhost
InetAddress addr = InetAddress.getByName(null);
//Connect to the server on pprt 9090
Socket s = new Socket(addr,9090);
// read and write to server using buffer reader and printwriter
try{
BufferedReader in = new BufferedReader(
new InputStreamReader(
s.getInputStream()
)
);
PrintWriter out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(s.getOutputStream())
)
);
//Get the Ipute string from user
Scanner input = new Scanner(System.in);
while (true){
System.out.println("Enter your text:");
String line = input.nextLine();
if(line.equals("quit"))
break;
// Sent the input string to the server using 'out'
out.println(line);
// Recive the upper case string from server
String response = in.readLine();
System.out.println("Echo:... " + response);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
System.out.println("closing...");
s.close();
}
}
}
The server side is waiting to read a line from the client, it should work if you flush the PrintWriter on the client side:
// Sent the input string to the server using 'out'
out.println(line);
out.flush();
This is the code for my server, its supposed to take an input from the user, print it into console, then send it back to the user.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class DateServer {
public static void main(String[] args) throws Exception {
ServerSocket listener = new ServerSocket(10219);
Socket s = listener.accept();
InputStreamReader in = new InputStreamReader(s.getInputStream());
BufferedReader input = new BufferedReader(in);
PrintWriter out = new PrintWriter(s.getOutputStream());
out.println("connected");
out.flush();
System.out.println("connected");
String test;
while (true) {
try {
test = input.readLine();
System.out.println(test);
out.println(test + " is what I recieved");
out.flush();
} catch(Exception X) {System.out.println(X);}
}
}
}
This is the code for the client:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.*;
public class DateClient {
public static Scanner keyboard = new Scanner(System.in);
public static void main(String[] args) throws Exception {
System.out.println("Enter IP Address of a machine that is");
System.out.println("running the date service on port 10219:");
String serverAddress = keyboard.next();
Socket s = new Socket(serverAddress, 10219);
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream());
System.out.println(input.readLine());
while(true){
try{
System.out.println(input.readLine());
out.println(keyboard.next());
out.flush();
} catch(Exception X){System.out.println(X);}
}
}
}
This was designed to work across a LAN network. I have no idea why it doesn't work, all that happens is the client will get the message "connected" and nothing else will happen, no matter what is typed into the client end. I'm a noob when it comes to java, but after a bunch of googling and searching through the java libraries, I can't seem to make it work. What did I do wrong?
You send one line from the server to the client, but in your client you wait for two lines before accepting user input to be sent to the server.
Bearing in mind that input.readLine() will block until data is received, can you spot the deadlock here:
Server:
out.println("connected");
while (true) {
try {
input.readLine();
}
}
Client:
input.readLine();
while(true) {
try {
input.readLine();
out.println(keyboard.next());
}
}
(extraneous code trimmed away to show just the problematic sequence of statements)
Both your client and server mutually wait for each other trying to do input.readLine().
This can be easily seen if you remove server's out.println("connected") and its corresponding client's first input.readLine().
On the client, you should probably write first and only then read the response. Try reordering the following lines:
System.out.println(input.readLine());
out.println(keyboard.next());
out.flush();
to get
out.println(keyboard.next());
out.flush();
System.out.println(input.readLine());
In the client, try changing
PrintWriter out = new PrintWriter(s.getOutputStream());
System.out.println(input.readLine());
while(true){
try{
System.out.println(input.readLine());
out.println(keyboard.next());
out.flush();
} catch(Exception X){System.out.println(X);}
}
to
PrintWriter out = new PrintWriter(s.getOutputStream());
while(true){
try{
System.out.println(input.readLine());
out.println(keyboard.nextLine());
out.flush();
} catch(Exception X){System.out.println(X);}
}
Your client is trying to read two lines, but your server sends just one, then polls for input, so both are locked. Also, sinc your server is reading line-by-line, your client should be sending data line-by-line.
I recently programmed a simple Java server, and a client to test the server. The server is supposed to receive messages from the client, and send a random substring of the message back. The problem is this: When I send the message using the client program, the server does not respond. Then, when I kill the client program, the server leaps into action, and attempts to send the data back to the client. The server reads the data correctly but starts processing it only when I stop the client program.
This is the client code:
import java.io.*;
import java.net.*;
class ServerTest{
public static void main(String args[]) throws Exception{
Socket clientSocket = new Socket(myIpAdress, 8001);
//Send the message to the server
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
String sendMessage = "randSubstring:StackOverflowIsAwsome";
bw.write(sendMessage);
bw.flush();
System.out.println("Message sent: "+sendMessage);
String message = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())).readLine();
System.out.println("Message received from the server : " +message);
clientSocket.close();
}
}
My server code consists of two classes. This one is the listener:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerListener {
public static void main(String args[]) throws Exception {
String clientSentence;
ServerSocket socket = new ServerSocket(8001);
while(true) {
Socket connectionSocket = socket.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
//DataOutputStream output = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = input.readLine();
if(clientSentence.startsWith("randSubstring:")){
Thread connection = new Thread(new ServerConnection(connectionSocket, clientSentence));
connection.start();
}
Thread.sleep(300);
}
}
}
This is the thread that will not start until the client is stopped:
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Random;
public class ServerConnection implements Runnable{
private Socket serverConnection;
private String sentence;
public ServerConnection(Socket connection, String clientSentence){
serverConnection = connection;
sentence = clientSentence;
}
#Override
public void run() {
Random r = new Random();
String substring = sentence.substring(0, r.nextInt(sentence.length()));
try {
OutputStream os = serverConnection.getOutputStream();
OutputStream out = new BufferedOutputStream(os);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
bw.write(substring);
bw.close();
out.close();
os.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I am using a Macintosh with Yosemite. Is this happening because I am trying to run the programs on the same computer, or would the problem occur if the programs were run from different computers? Any help is appreciated.
In the server you do a readLine(..), which means that it will wait for a end-of-line character.
But in your sender code, you just send a string with no line ending.
So either you make sure you also send a end of line char or your server wait's for something else as "delimiter"
You're reading a line but you aren't writing a line. Add a line terminator to the sent message. Otherwise readLine() won't return until the peer closes the connection.
NB The I/O in the try block after the accept should be in the Runnable, not where it is. Don't do I/O in the accept loop.
My S/W simulation of GoBack N protocol gives warning- [deprecation] readLine() in DataInputStream has been deprecated (while reading from streams) while running both client & server programs .Please tell me a solution.Is there any alternative for readLine()? Here is my client/server programs
//Server Program
import java.io.*;
import java.net.*;
import java.lang.*;
public class gobacksender
{
public static void main(String[] args)throws Exception
{
//Establishing connection
ServerSocket ss=new ServerSocket(4444);
System.out.println("Waiting for connection........");
Socket s=ss.accept();
System.out.println("Connected to client at:"+s);
DataInputStream in=new DataInputStream(System.in);
DataInputStream in1=new DataInputStream(s.getInputStream());
PrintStream p=new PrintStream(s.getOutputStream());
int sptr=0,sws=8,i,ano,nf,n;
String sbuf[]=new String[8];
String ch,ch1;
System.out.println("Enter the no.of frames");
nf=Integer.parseInt(in.readLine());
p.println(nf);
if(nf<=sws-1)
{
System.out.println("Enter the "+nf+" messages to be send");
for(i=1;i<=nf;i++)
{
sbuf[sptr]=in.readLine();
p.println(sbuf[sptr]);
sptr=++sptr%8;
}
sws-=nf;
do
{
ano=Integer.parseInt(in.readLine());
System.out.println("Received acknowledgement for:"+ano);
System.out.println("Retransmitting...............");
for(i=ano-1;i<nf;i++)
p.println(i);
ch1=in1.readLine();
}while(ch1.equals("yes"));
sws+=nf;
}
else
{
System.out.println("the no.of frames exceed window size");
}
ano=Integer.parseInt(in1.readLine());
System.out.println("Acknowledgement received for"+ano+"frames");
s.close();
}
}
//Client Program
import java.io.*;
import java.net.*;
import java.lang.*;
public class gobackreceiver
{
public static void main(String[] args)throws Exception
{
//Connection establishment
Socket s=new Socket("localhost",4444);
System.out.println("Connected to server at:"+s);
DataInputStream in=new DataInputStream(System.in);
DataInputStream in1=new DataInputStream(s.getInputStream());
PrintStream p=new PrintStream(s.getOutputStream());
String rbuf[]=new String[8];
int i,rptr=0,rws=8,nf,n;
String ch,ch1;
do
{
nf=Integer.parseInt(in1.readLine());
System.out.println("No.of messages",nf);
if(nf<rws)
{
for(i=1;i<=nf;i++)
{
rbuf[rptr]=in1.readLine();
rptr=++rptr%8;
System.out.println("The received frame"+(rptr+1)+"is:"+rbuf[rptr]);
}
rws-=nf;
do
{
System.out.println("Enter the nak number");
n=Integer.parseInt(in.readLine());
if((1<=n)&&(n<=nf))
{
p.println(n);
for(i=n;i<nf;i++)
{
rbuf[i]=in1.readLine();
System.out.println("the received frame"+i+"is;"+rbuf[i]);
}
}
else
{
System.out.println("Invalid nak");
}
System.out.println("Anymore frames lost?");
ch1=in.readLine();
p.println(ch1);
}while(ch1.equals("yes"));
System.out.println("Ack sent");
p.println(rptr+1);
rws+=nf;
}
else
break;
ch=in.readLine();
}while(ch.equals("yes"));
s.close();
}
}
Copied from the Java API Docs:
Deprecated.
This method does not properly convert bytes to characters. As of JDK 1.1, the preferred way to read lines of text is via the BufferedReader.readLine() method. Programs that use the DataInputStream class to read lines can be converted to use the BufferedReader class by replacing code of the form:
DataInputStream d = new DataInputStream(in);
with:
BufferedReader d
= new BufferedReader(new InputStreamReader(in));
If you get such warnings, your first look should always be on the API or at least googling..
I am trying to make a simple server/client application to get my head around using sockets. I can successfully get single line communication between server and client, for example client sends message to server, server acknowledges and sends single message back.
The problem is when I try to read the incoming replies from the server back to the client when there are multiple lines in the BufferedReader.
Examples...
Server and client giving one line to each other.
import java.io.*;
import java.net.*;
import java.awt.*;
class Server {
public static void main(String args[])throws IOException
{
Server myServ = new Server();
myServ.run();
}//end main
public void run() throws IOException
{
ServerSocket serSKT = new ServerSocket(729);
Socket socket = serSKT.accept();
BufferedReader BR = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter PW = new PrintWriter(socket.getOutputStream());
String fromClient = BR.readLine();
System.out.println(fromClient);
if(fromClient !=null)
{PW.println("Server giving response to client");PW.flush();}
}}//end class server
Client:
import java.io.*;
import java.net.*;
class Client
{
public static void main(String args[])throws IOException
{
Client myCli = new Client();
myCli.run();
}
public void run() throws IOException
{
int port = 729;
Socket mySkt = new Socket("localhost",port);
PrintWriter myPW = new PrintWriter(mySkt.getOutputStream(),true);
BufferedReader myBR = new BufferedReader(new InputStreamReader(mySkt.getInputStream()));
myPW.println("Message from client to server");
String temp=myBR.readLine();
System.out.println(temp);
}}
So the above works fine..now when I try to use for loops to print 10 lines of text to the server and then 10 lines back from the server to the client, I run in to problems. For example..Here is the server and client..
import java.io.*;
import java.net.*;
import java.awt.*;
class Server {
public static void main(String args[])throws IOException
{
Server myServ = new Server();
myServ.run();
}//end main
public void run() throws IOException
{
ServerSocket serSKT = new ServerSocket(729);
Socket socket = serSKT.accept();
BufferedReader BR = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter PW = new PrintWriter(socket.getOutputStream());
String fromClient = null;
while((fromClient = BR.readLine())!=null)
{
System.out.println(fromClient);//this is being printed successfully
}
if(fromClient !=null)
{
for(int i=0;i<10;i++){
PW.println("Server giving response to client"+i);}
PW.flush();}
}}//end class server
Client:
import java.io.*;
import java.net.*;
class Client
{
public static void main(String args[])throws IOException
{
Client myCli = new Client();
myCli.run();
}
public void run() throws IOException
{
int port = 729;
Socket mySkt = new Socket("localhost",port);
PrintWriter myPW = new PrintWriter(mySkt.getOutputStream(),true);
BufferedReader myBR = new BufferedReader(new InputStreamReader(mySkt.getInputStream()));
for(int i =0;i<10;i++)
myPW.println("Message from client to server"+i);
String temp=null;
while((temp=myBR.readLine())!=null){
System.out.println(temp);}
}}
The above will print the message 10 times to the server and the server will display what the client has sent it successfully:
while((fromClient = BR.readLine())!=null)
{
System.out.println(fromClient);//this is being printed successfully
}
What I do not understand is why the client will not get the message "Server giving response to client" and print it to the console:
String temp=null;
while((temp=myBR.readLine())!=null){
System.out.println(temp);} //should be printing "Server giving repsonse to client"
Sorry it is long, thanks but I am trying with no success!
****EDIT***
Incase anyone else comes across this problem, This was solved by printing a command to the printwriter in the client class to allow the server to know it has finished. e.g:
for(int i =0;i<10;i++){
myPW.println("Message from client to server"+i);}
myPW.println("Finished");
Now in the server class the text being sent to it should be checked for the "Finished" command, if so, break out of the while loop and start sending back to the client, I believe that the only way BufferedReader will be null is if it is closed, so it is infinitely looping. Thanks for the help everyone.
while((fromClient = BR.readLine())!=null)
{
if(fromClient.equals("Finished"))
{
break;
}
System.out.println(fromClient);
}
It looks like you never exit the while() loop in the server, after the 10th line, the server waits for another line (and another, and another, etc.).
The client has to notify the server that he has finished sending, e.g. by sending a special line.
Then you should exit the while loop on the server and start sending.
I think the issue is with:
while((fromClient = BR.readLine())!=null)
{
System.out.println(fromClient);//this is being printed successfully
}
BR.readLine() will not return null until the stream ends (eg is closed/disconnected). You shouldn't use this as your break condition, it will wait inside readLine() for more data to appear on the stream.
You are waiting for the client to close the stream i.e. when br.readLine() == null before sending anything. After this happens fromClient will be null in which case you send nothing anyway
I suggest you try
for (String s; (s = BR.readLine())!=null;) {
System.out.println(s);
PW.println("Server response to " + s);
}