Reading data from a socket java - java

So, I'm trying to read data from a socket. I have established a connection and sent a message to the other socket which is listening for such, but it doesn't seem to recieve anything.
Client code:
import java.net.*;
import java.io.*;
import java.util.*;
public class TCPClient {
/*Conecting to server.
*/
public static void Client(String[] args){
int port = 47361;
Scanner in = new Scanner(System.in);
System.err.print("Starting up...");
Socket CS1 = null; //Declaring CS1 as a socket
DataOutputStream DOS1 = null; //Declaring an outputput data stream "DOS1"
DataInputStream DIS1 = null; //Setting the values to null
System.err.println("All created.");
System.out.println("---------");
System.out.println(" OPTIONS");
System.out.println("---------");
System.out.println("0. Connect.");
System.out.println("1. Change port.");
System.out.println("2. Cancel start-up.");
System.out.println("");
System.out.println("Choose an option.");
try {
short ans = in.nextShort();
if (ans == 2){
System.err.println("System.exit(0)");
System.exit(0);
}
if (ans == 1){
System.out.print("Enter the new port: ");
port = in.nextInt();
ans = 0;
}
if (ans == 0){
System.out.print("Enter the IP: ");
CS1 = new Socket(in.next(), port); //Creating an instane of the "CS1" socket
System.err.print("Request sent on port " + port + ".");
DOS1 = new DataOutputStream(CS1.getOutputStream());
DIS1 = new DataInputStream(CS1.getInputStream()); //creating output and input streams
System.err.println("Instances created!");
if (DIS1 != null){
System.err.println("DIS1 is connected!");
}
else {
System.err.println("DIS1 is null!");
}
if (DOS1 != null) {
System.err.println("DOS1 is connected!");
System.out.print("Enter input: ");
String FirstMessage = in.nextLine();
DOS1.writeBytes(FirstMessage);
String SecondMessage = DIS1.readLine();
System.out.println(SecondMessage);
if (SecondMessage.equals(FirstMessage)) {
}
else {
System.out.println("Please check the code, FirstMessage != SecondMessage");
}
}
else {
System.err.println("DOS1 is null!");
}
if (CS1 != null) {
System.err.println("CS1 is connected!");
}
else {
System.err.println("CS1 is null!");
}
DIS1.close();
DOS1.close();
CS1.close(); //closing everything
}
}
catch (IOException e){
System.err.println("IOException: " + e.getMessage());
}
}
}
Server code:
import java.net.*;
import java.io.*;
import java.util.*;
public class TCPServer {
/*Connecting to client
*/
public static void Server (String[] args) {
System.err.print("Starting up...");
ServerSocket SS1 = null;
DataOutputStream DOS1 = null;
DataInputStream DIS1 = null;//Setting the values to null
System.err.println("All created.");
Scanner in = new Scanner(System.in);
try {
SS1 = new ServerSocket(47361); //setting the socket SS1 to port 5000 and creating an instance
System.err.print("Listening on port 47361...");
Socket CS1 = SS1.accept(); //accepting the connection request
DOS1 = new DataOutputStream(CS1.getOutputStream());
DIS1 = new DataInputStream(CS1.getInputStream());//creating output and input streams
System.err.println("Instances created!");
if (DIS1 != null){
System.err.println("DIS1 is connected!");
System.err.println(DIS1);
}
else {
System.err.println("DIS1 is null!");
}
if (DOS1 != null) {
System.err.println("DOS1 is connected!");
System.err.println(DOS1);
}
else {
System.err.println("DOS1 is null!");
}
if (SS1 != null) {
System.err.println("SS1 is connected!");
System.err.println(SS1);
}
else {
System.err.println("SS1 is null!");
}
String FirstMessage = null;
FirstMessage = DIS1.readLine();
System.out.println(FirstMessage);
String SecondMessage = FirstMessage;
DOS1.writeBytes(SecondMessage);
DIS1.close();
DOS1.close();
SS1.close(); //closing everything
}
catch (IOException error){
System.err.println("IOException " + error.getMessage());
}
catch (java.util.InputMismatchException error2){
System.err.println("IOException " + error2.getMessage());
}
}
}
It's pretty much an EchoServer so far, without Buffered. I looked in the debugger and it gets stuck on the FirstMessage = DIS1.readLine(); line in the server and the String SecondMessage = DIS1.readLine(); in the client. Also, both the server and client are waiting for input even after I've entered any possible input. Why is this happenenig? And how can I make this work?
A side note: I know that an i/o stream or a socket will not, ever, equal null. Also, the compiler is warning me that the class java.io.DataInputStream has been deprecated. What other classes do you recommend using?
Another side note: I am new to IO, please don't kill me about it haha :)
Thanks!

Usual problem. You're reading lines but you're not writing lines. Add a line terminator to the message when writing.

Related

Java DatagramSocket Diferrent Thread for every client request

I'm working on a project in Java where clients send via DatagramSocket a basic calculation (eg 5+6) and the Server needs to reply with the result. The goal is to have a different thread calculating each different client request. So far I have this code:
Client:
import java.net.*;
import java.io.*;
public class UDPClient {
public static void main (String args[]){
DatagramSocket aSocket = null;
int input=-1;
String operation=null;
while(input!=0){
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Select an option");
System.out.println("1. Do a basic calculation");
System.out.println("0. Exit ");
try{
input = Integer.parseInt(br.readLine());
if(input>1 | input<0)throw new Exception("Error");
}
catch(Exception e){
System.out.println("Wrong selection...Try again \n");
}
if(input==1)
{
System.out.println("Give operator symbol (+,-,*,/) ");
try{
String operator = br.readLine();
if(!(operator.matches("[*]|[+]|[/]|[-]")))throw new Exception("Error");
System.out.println("Give first number");
int first = Integer.parseInt(br.readLine());
System.out.println("Give second number");
int second = Integer.parseInt(br.readLine());
operation = first+":"+operator+":"+second;
send:
try{
aSocket = new DatagramSocket();
byte [] m = operation.getBytes();
InetAddress aHost = InetAddress.getByName(args[1]);
int serverPort = 6789;
DatagramPacket request = new DatagramPacket(m, m.length, aHost, serverPort);
aSocket.send(request);
aSocket.setSoTimeout(10000); // SocketTimeout happens here
byte[]buffer = new byte[1000];
DatagramPacket reply = new DatagramPacket(buffer, buffer.length);
aSocket.receive(reply);
System.out.println("Reply:" + new String(reply.getData()));
}
catch (SocketTimeoutException e) {
System.out.println("Server reply timeout");
break send; //If Timeout happens, send request again
}
catch(SocketException e){
System.out.println("Socket: " + e.getMessage());
}
catch(IOException e){
System.out.println("IO: " + e.getMessage());
}
finally {if (aSocket!=null) aSocket.close();}
}
catch(Exception e){
System.out.println("Wrong input...Try again \n");
}
}//End of if
}//end of while
}
}
Server:
import java.net.*;
import java.nio.charset.Charset;
import java.io.*;
public class UDPServer {
static DatagramSocket aSocket = null;
public static void main (String args[]){
int i=0;
try{
aSocket = new DatagramSocket(6789);
byte[] buffer = new byte[1000];
while(true){
DatagramPacket request = new DatagramPacket(buffer, buffer.length);
aSocket.receive(request);
new ClientThread(aSocket,request);
}
}
catch(SocketException e){
System.out.println("Socket: " + e.getMessage());
}
catch(IOException e){
System.out.println("IO: " + e.getMessage());
}
}
}
class ClientThread extends Thread{
DatagramSocket sock;
DatagramPacket request;
public ClientThread(DatagramSocket sock, DatagramPacket request){
this.sock=sock;
this.request=request;
this.start();
}
public void run() {
try{
String input = new String(request.getData());
String[] in = input.split("[:]");
double temp=0;
if (in[1].matches("[+]")) temp = Double.valueOf(in[0])+Double.valueOf(in[2]);
if (in[1].matches("[-]")) temp = Double.valueOf(in[0])-Double.valueOf(in[2]);
if (in[1].matches("[*]")) temp = Double.valueOf(in[0])*Double.valueOf(in[2]);
if (in[1].matches("[/]")) temp = Double.valueOf(in[0])/Double.valueOf(in[2]);
String result ="Result: "+temp + " from Thread: "+ Thread.currentThread().getName() + "\n";
DatagramPacket reply = new DatagramPacket(result.getBytes(Charset.forName("UTF-8")),
result.length(),request.getAddress(),request.getPort());
//sock.send(reply);
System.out.println(result);
}
/*
catch(SocketException e){
System.out.println("Socket: " + e.getMessage());
}
catch(IOException e){
System.out.println("IO: " + e.getMessage());
}
*/
finally {}
}
}
I have two basic problems
1) If I send a second request from Client (first one executes fine) it causes the Server to output a Socket closed error message.
2) As you can see In Server side I've currently commented sock.send(reply) so I can check the timeout code I've added in the Client's side. The problem is that after timeout happens (since no reply is ever send) code starts from the beginning and not the send label I specified inside the TimeoutException catch().
If anyone can help me with any of those two problems, I would be very gratefull
Thanks in advance for your time!!!
Create the socket ahead of the loop. At present you're letting it be garbage-collected.
Your statement that the socket timeout happens at the setSoTimeout() call is incorrect. It happens at the receive() call.
Revised code seems to be working. Let me know your opinion on this
Client:
import java.net.*;
import java.io.*;
public class UDPClient {
public static void main (String args[]){
DatagramSocket aSocket = null;
int input=-1; //User Input from menu
String operation=null; //keeps the calculation operation in String form
int resends=0; //NACK counter
while(input!=0){
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Select an option");
System.out.println("1. Do a basic calculation");
System.out.println("0. Exit ");
try{
input = Integer.parseInt(br.readLine());
if(input>1 | input<0)throw new Exception("Error");
}
catch(Exception e){
System.out.println("Wrong selection...Try again \n");
}
if(input==1)
{
System.out.println("Give operator symbol (+,-,*,/) ");
try{
String operator = br.readLine();
if(!(operator.matches("[*]|[+]|[/]|[-]")))throw new Exception("Error");
System.out.println("Give first number");
int first = Integer.parseInt(br.readLine());
System.out.println("Give second number");
int second = Integer.parseInt(br.readLine());
operation = first+":"+operator+":"+second;
}
catch(Exception e){
System.out.println("Wrong input...Try again \n");
System.out.println(e.getMessage());
}
while(true){
try{
if(resends==3){ // At 3 resends break loop
resends=0;
break;
}
aSocket = new DatagramSocket();
byte [] m = operation.getBytes();
InetAddress aHost = InetAddress.getByName(args[1]);
int serverPort = 6789;
DatagramPacket request = new DatagramPacket(m, m.length, aHost, serverPort);
aSocket.send(request);
resends++;//counting times we send this message
aSocket.setSoTimeout(30000); // Setting timeout for socket (30 sec)
byte[]buffer = new byte[1000];
DatagramPacket reply = new DatagramPacket(buffer, buffer.length);
aSocket.receive(reply);
System.out.println("Reply:" + new String(reply.getData()));
if(reply!=null)break; // If you get a reply, break loop
}
catch (SocketTimeoutException e) {
System.out.println("Server reply timeout");
}
catch(SocketException e){
System.out.println("Socket: " + e.getMessage());
}
catch(IOException e){
System.out.println("IO: " + e.getMessage());
}
finally {if (aSocket!=null) aSocket.close();}
}// end of send while loop
}//End of if
else if (input==0)
System.out.println("Exiting UDP Client.....");
}//end of while
}//end of main
}//end of Class
Server:
import java.net.*;
import java.nio.charset.Charset;
import java.io.*;
public class UDPServer {
public static void main (String args[]){
DatagramSocket aSocket = null;
try{
aSocket = new DatagramSocket(6789);
byte[] buffer = new byte[1000];
while(true){
DatagramPacket request = new DatagramPacket(buffer, buffer.length);
aSocket.receive(request);
new ClientThread(aSocket,request);
}
}
catch(SocketException e){
System.out.println("Socket: " + e.getMessage());
}
catch(IOException e){
System.out.println("IO: " + e.getMessage());
}
finally {if(aSocket!=null)aSocket.close();}
}
}
class ClientThread extends Thread{
DatagramSocket sock;
DatagramPacket request;
public ClientThread(DatagramSocket sock, DatagramPacket request){
this.sock=sock;
this.request=request;
this.start();
}
public void run() {
try{
String input = new String(request.getData());
String[] in = input.split("[:]");
String result;
double temp=0;
if (in[1].matches("[+]")) temp = Double.valueOf(in[0])+Double.valueOf(in[2]);
if (in[1].matches("[-]")) temp = Double.valueOf(in[0])-Double.valueOf(in[2]);
if (in[1].matches("[*]")) temp = Double.valueOf(in[0])*Double.valueOf(in[2]);
if (in[1].matches("[/]")) temp = Double.valueOf(in[0])/Double.valueOf(in[2]);
result ="Result: "+temp + " from Thread: "+ Thread.currentThread().getName() + "\n";
DatagramPacket reply = new DatagramPacket(result.getBytes(Charset.forName("UTF-8")),
result.length(),request.getAddress(),request.getPort());
sock.send(reply);
//System.out.println(result);
}
catch(SocketException e){
System.out.println("Socket: " + e.getMessage());
}
catch(IOException e){
System.out.println("IO: " + e.getMessage());
}
}
}
In Client side, args[1] represents the Server's IP address. You can use "127.0.0.1" if your Server is running on Localhost.

iterative dictionary server in java

what it do..
1. an iterative dictionary server that is listening clients requests..
2. connection will be established..
3. server will accept input string from client..
4. then server will search meaning of string from a file..
5. then server will return meaning to the client..
problem is with the while loop of server.. if it finds word it will send that word's meaning to client..fine.. but if word is not found... this
if(d.equals(null)){
input="No knowledge";
out.println(input);
out.flush();
}
doesn't execute... client says null and server says null exception...
what i am doing wrong here... i'm not getting it...!!
i have tried to changed this code...
client-server online dictionary program in java
client:
import java.io.;
import java.net.;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class DCC1 {
public static void main(String[] args) throws IOException {
final int PORT = 8888;
Socket s = null;
PrintWriter out = null;
try {
s = new Socket("localhost", PORT);
out = new PrintWriter(s.getOutputStream()); // Output stream to the server
}
catch (UnknownHostException ex) {
System.err.println("Unknown host: " + PORT);
System.err.println("Exception: " + ex.getMessage());
System.exit(1);
}
catch (IOException ex) {
System.err.println("Cannot get I/O for " + PORT);
System.err.println("Exception: " + ex.getMessage());
System.exit(1);
}
Scanner user = new Scanner(System.in); // Scanning for user input
System.out.print("Enter String: ");
String input;
input = user.next(); // Hold the input from the user
out.println(input); // Send it to the server
out.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream( )));
System.out.println(br.readLine());
out.close();
s.close();
}
}
server:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class DSC1
{
public static void main(String[] args) throws IOException
{
final int PORT = 8888;
final String FILE_NAME = "dictionary.dat";
ServerSocket server = new ServerSocket(PORT);
Socket s = null;
PrintWriter out = null;
Scanner in = null;
FileInputStream fin = null;
ObjectInputStream oin = null;
while (true)
{
try
{
s = server.accept();
}
catch (IOException ex)
{
System.err.println("Accept failed");
System.err.println("Exception: " + ex.getMessage());
System.exit(1);
}
System.out.println("Accepted connection from client");
try
{
in = new Scanner(s.getInputStream()); // Input stream from the client
out = new PrintWriter(s.getOutputStream()); // Output stream to the client
String temp = in.next(); // String holding the word sent from the client
System.out.println("From the client " + temp);
String input = null;
fin = new FileInputStream(FILE_NAME);// The dictionary file
oin = new ObjectInputStream(fin);
dictionary d = (dictionary)oin.readObject();
while(d!= null)
{
System.out.println("in loop...");
if(d.name.equals(temp)){
input=d.meaning;
d.printDic();
out.println(input);
out.flush();
break;
}
d = (dictionary)oin.readObject();
if(d.equals(null))
{
input="No knowledge";
out.println(input);
out.flush();
}
}
}
catch (ClassNotFoundException|IOException ex)
{
System.err.println("Exception: " + ex.getMessage());
System.out.println("Closing connection with client");
in.close();
System.exit(1);
}
in.close();
}
}
}
Don't use d.equals(null). If you want to check if d is null, just do if (d==null).
Why? There's no way this can return true, so probably that's the reason why this code never executes and you don't get what you expect.

Server not receiving in socket communication

I'm trying to make a Java program in which the server generates a random number and, after establishing a connection with a client, lets it guess the number. However, they both don't seem able to receive each others' messages.
Server side:
package numberguessserv;
import java.net.*;
import java.io.*;
import java.util.Random;
import java.util.Scanner;
public class NumberGuessServ {
public static void main(String[] args) {
Scanner inpkb = new Scanner(System.in);
Random randomGenerator = new Random();
int randomNum = randomGenerator.nextInt(10);
String number = Integer.toString(randomNum);
int port;
boolean isGuessed = false;
String msgReceived;
Socket connect = new Socket();
System.out.print("port: ");
port = inpkb.nextInt();
try {
ServerSocket clSock = new ServerSocket(port);
System.out.println("Waiting...");
connect = clSock.accept();
System.out.println("Connection established with"+connect.getInetAddress());
InputStreamReader isr = new InputStreamReader(connect.getInputStream());
BufferedReader isrBuff = new BufferedReader(isr);
OutputStreamWriter osw = new OutputStreamWriter(connect.getOutputStream());
BufferedWriter oswBuff = new BufferedWriter(osw);
while (!isGuessed) {
msgReceived = isrBuff.readLine();
System.out.println("Number received: "+msgReceived);
if (msgReceived.equals(number)) {
isGuessed = true;
oswBuff.write("Right!");
oswBuff.flush();
}
else {
oswBuff.write("Wrong!");
oswBuff.flush();
}
if (isGuessed)
System.out.println("Number was guessed right.");
else
System.out.println("Number was guessed wrong.");
}
}
catch (Exception ex) {
System.out.println("An exception has occurred: "+ex);
}
finally {
try {
connect.close();
}
catch (Exception ex) {
System.out.println("An exception has occurred: "+ex);
}
}
}
}
Client side:
package numberguessclient;
import java.io.*;
import java.util.Scanner;
import java.net.*;
public class NumberGuessClient {
public static void main(String[] args) {
Scanner inpkb = new Scanner(System.in);
int port;
String IP;
boolean isGuessed = false;
String number, msg;
Socket serv = new Socket();
System.out.print("IP: ");
IP = inpkb.next();
System.out.print("port: ");
port = inpkb.nextInt();
try {
serv = new Socket(IP,port);
System.out.println("Connetion established with"+serv.getInetAddress());
InputStreamReader isr = new InputStreamReader(serv.getInputStream());
BufferedReader isrBuff = new BufferedReader(isr);
OutputStreamWriter osw = new OutputStreamWriter(serv.getOutputStream());
BufferedWriter oswBuff = new BufferedWriter(osw);
while (!isGuessed) {
System.out.print("number: ");
number = inpkb.next();
oswBuff.write(number);
oswBuff.flush();
System.out.println("Number sent.");
msg = isrBuff.readLine();
System.out.println("The reply was received: "+msg);
if (msg.equals("Right!")) {
isGuessed = true;
System.out.println(msg);
}
else {
System.out.println(msg+"\nTry again...");
}
}
}
catch (Exception ex) {
System.out.print("An exception has occurred: "+ex);
}
finally {
try {
serv.close();
}
catch (Exception ex) {
System.out.print("An exception has occurred: "+ex);
}
}
}
}
The readLine() waits for the end of line. Unless and until it gets a new line character, it will wait up there reading.
So, you need to give a new line characer '\n' every time you give an input to the output stream so that the readLine() reads a new line character and does not wait.
Currently in your code, you need to give a new line character everytime you are giving input by doing the following:
oswBuff.write("any message");
oswBuff.write('\n'); //add this statement everywhere you are writing to the output stream
oswBuff.flush();
This complies well for both the server as well as client.
That's expected. Both ends read using
isrBuff.readLine();
So, they both expect the other end to send a line. But none of them sends a line. They both do
oswBuff.write(number);
oswBuff.flush();
That sends some characters, but doesn send any newline character. The receiving end doesn't have any way to know that the end of line has been reached, and it thus continues blocking until it receives the EOL.

java.lang.NullPointerException and java.net.SocketException

I’m trying to socket program in Java. Here the client sends a string which should be reversed by the server and sent back to the client. The server is a multithreaded server. Here is the client-side code:
import java.io.*;
import java.net.*;
class ClientSystem
{
public static void main(String[] args)
{
String hostname = "127.0.0.1";
int port = 1234;
Socket clientsocket = null;
DataOutputStream output =null;
BufferedReader input = null;
try
{
clientsocket = new Socket(hostname,port);
output = new DataOutputStream(clientsocket.getOutputStream());
input = new BufferedReader(new InputStreamReader(clientsocket.getInputStream()));
}
catch(Exception e)
{
System.out.println("Error occured"+e);
}
try
{
while(true)
{
System.out.println("Enter input string ('exit' to terminate connection): ");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String inputstring = br.readLine();
output.writeBytes(inputstring+"\n");
//int n = Integer.parseInt(inputstring);
if(inputstring.equals("exit"))
break;
String response = input.readLine();
System.out.println("Reversed string is: "+response);
output.close();
input.close();
clientsocket.close();
}
}
catch(Exception e)
{
System.out.println("Error occured."+e);
}
}
}
Here is the server side code:
import java.io.*;
import java.net.*;
public class ServerSystem
{
ServerSocket server = null;
Socket clientsocket = null;
int numOfConnections = 0, port;
public ServerSystem(int port)
{
this.port = port;
}
public static void main(String[] args)
{
int port = 1234;
ServerSystem ss = new ServerSystem(port);
ss.startServer();
}
public void startServer()
{
try
{
server = new ServerSocket(port);
}
catch(Exception e)
{
System.out.println("Error occured."+e);
}
System.out.println("Server has started. Ready to accept connections.");
while(true)
{
try
{
clientsocket = server.accept();
numOfConnections++;
ServerConnection sc = new ServerConnection(clientsocket, numOfConnections, this);
new Thread(sc).start();
}
catch(Exception e)
{
System.out.println("Error occured."+e);
}
}
}
public void stopServer()
{
System.out.println("Terminating connection");
System.exit(0);
}
}
class ServerConnection extends Thread
{
BufferedReader br;
PrintStream ps;
Socket clientsocket;
int id;
ServerSystem ss;
public ServerConnection(Socket clientsocket, int numOfConnections, ServerSystem ss)
{
this.clientsocket = clientsocket;
id = numOfConnections;
this.ss = ss;
System.out.println("Connection "+id+" established with "+clientsocket);
try
{
br = new BufferedReader(new InputStreamReader(clientsocket.getInputStream()));
ps = new PrintStream(clientsocket.getOutputStream());
}
catch(Exception e)
{
System.out.println("Error occured."+e);
}
}
public void run()
{
String line, reversedstring = "";
try
{
boolean stopserver = false;
while(true)
{
line = br.readLine();
System.out.println("Received string: "+line+" from connection "+id);
//long n = Long.parseLong(line.trim());
if(line.equals("exit"))
{
stopserver = true;
break;
}
else
{
int len = line.length();
for (int i=len-1; i>=0; i--)
reversedstring = reversedstring + line.charAt(i);
ps.println(""+reversedstring);
}
}
System.out.println("Connection "+id+" is closed.");
br.close();
ps.close();
clientsocket.close();
if(stopserver)
ss.stopServer();
}
catch(Exception e)
{
System.out.println("Error occured."+e);
}
}
}
I get a java.lang.NullPointerException on the server side code when I enter the string and when i try to re-enter the string I get a java.net.SocketException: Socket closed exception.
Client side output:
Enter input string ('exit' to terminate connection):
usa
Reversed string is: asu
Enter input string ('exit' to terminate connection):
usa
Error occured.java.net.SocketException: Socket closed
Server side output:
Server has started. Ready to accept connections.
Connection 1 established with Socket[addr=/127.0.0.1,port=3272,localport=1234]
Received string: usa from connection 1
Received string: null from connection 1
Error occured.java.lang.NullPointerException
I tried a lot but I don't get from where I get these exceptions.
These 3 lines are the culprits in the client code:
output.close();
input.close();
clientsocket.close();
Put them outside of the while loop, and in the finally block:
try {
while(true) {
// client code here
}
} catch (Exception e) {
e.printStackTrace(); // notice this line. Will save you a lot of time!
} finally {
output.close(); //close resources here!
input.close();
clientsocket.close();
}
The issue is that as it was originally, you closed every resource, but in the next iteration, you wanted to use them agai, without initialising them...
Sidenote
Properly handling exceptions including proper logging of them. Always use either a logging framework like log4j
LOG.error("Unexpected error when deionizing the flux capacitor",e);
, or the printStackTrace() method
e.printStackTrace();
And don't forget to include the line numbers in your code, if you post a stacktrace....
EDIT
For the reversed issue:
else
{
int len = line.length();
reversedString=""; //this line erases the previous content of the reversed string
for (int i=len-1; i>=0; i--) { //always use brackets!!!
reversedstring = reversedstring + line.charAt(i);
}
ps.println(""+reversedstring);
}
What happened? The reversedString just grew and grew with each iteration, without getting erased... This is why I like to declare my variables in just the most strict scope I need them.
EDIT
To make the exit command no tkill the server, this can be one (very simple) solution:
In the ServerConnection class:
while(true)
{
line = br.readLine();
System.out.println("Received string: "+line+" from connection "+id);
if(line.equals("exit"))
{
break; //just stop this connection, don't kill server
}
else if(line.equals("stop"))
{
stopserver = true; //stop server too
break;
}
else
{
int len = line.length();
for (int i=len-1; i>=0; i--) {
reversedstring = reversedstring + line.charAt(i);
}
ps.println(""+reversedstring);
}
}
What is happening here? There is a new "command" stop, which makes the server stop, and the exit just exits the client, but does not stop the server itself...
in the 1st run of the loop you are closing all the connections which is causing the issue.
output.close();
input.close();
clientsocket.close();,move it down
Your server is calling br.readLine(); It will wait until the client sends it, but once you send a String you call:
output.close();
input.close();
clientsocket.close();
That will release the resource and result in br.readLine() being null
if (line.equals("exit")) { Here line is null, therefore you cannot call equals.
if ("exit".equals(line)) { You can change it like this to prevent that exception here.
Move the close statements to a finally block, even in the server should, if you have an exception in the while, the close are never reached, that may cause memory leaks.
Client:
} finally {
output.close();
input.close();
clientsocket.close();
}
Server:
} finally {
br.close();
ps.close();
clientsocket.close();
}
Note: you can validate them before closing to ensure they are not null.
You may have to provide a case for the input being null anyway, either exit the loop, usually you would use something like this:
if (null==line || "exit".equals(line)) {
If the client sends a null, something is wrong.

Why is this basic client-server program not passing data?

I am following the Java Trail on networking. The three KnockKnock classes used as examples (client, server, and protocol) work as intended when I copy/paste them into Eclipse. However, what I really want to do is eliminate the protocol class and just have the server echo back to the client whatever I type into the console. I tried modifying the server program mainly by commenting out references to the protocol class, but somehow, I ended up breaking the program.
I am so new that I am clueless as to what is wrong and the more I search for an answer in ebooks and on websites the more confused I get. All I have discovered is that I know next to nothing about how IO streams really work. I pasted all three classes below in the order: server, client, protocol. Where is the problem and why is it a problem:
Server:
import java.net.*;
import java.io.*;
public class KnockKnockServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
System.out.println("Client Accepted");
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
String inputLine, outputLine;
//KnockKnockProtocol kkp = new KnockKnockProtocol();
//outputLine = kkp.processInput(null);
//out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
//outputLine = kkp.processInput(inputLine);
//out.println(outputLine);
out.println(inputLine);
if (inputLine.equals("Bye."))
break;
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
Client:
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("localhost", 4444);
out = new PrintWriter(kkSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: taranis.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: taranis.");
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();
}
}
Protocol:
import java.net.*;
import java.io.*;
public class KnockKnockProtocol {
private static final int WAITING = 0;
private static final int SENTKNOCKKNOCK = 1;
private static final int SENTCLUE = 2;
private static final int ANOTHER = 3;
private static final int NUMJOKES = 5;
private int state = WAITING;
private int currentJoke = 0;
private String[] clues = { "Turnip", "Little Old Lady", "Atch", "Who", "Who" };
private String[] answers = { "Turnip the heat, it's cold in here!",
"I didn't know you could yodel!",
"Bless you!",
"Is there an owl in here?",
"Is there an echo in here?" };
public String processInput(String theInput) {
String theOutput = null;
if (state == WAITING) {
theOutput = "Knock! Knock!";
state = SENTKNOCKKNOCK;
} else if (state == SENTKNOCKKNOCK) {
if (theInput.equalsIgnoreCase("Who's there?")) {
theOutput = clues[currentJoke];
state = SENTCLUE;
} else {
theOutput = "You're supposed to say \"Who's there?\"! " +
"Try again. Knock! Knock!";
}
} else if (state == SENTCLUE) {
if (theInput.equalsIgnoreCase(clues[currentJoke] + " who?")) {
theOutput = answers[currentJoke] + " Want another? (y/n)";
state = ANOTHER;
} else {
theOutput = "You're supposed to say \"" +
clues[currentJoke] +
" who?\"" +
"! Try again. Knock! Knock!";
state = SENTKNOCKKNOCK;
}
} else if (state == ANOTHER) {
if (theInput.equalsIgnoreCase("y")) {
theOutput = "Knock! Knock!";
if (currentJoke == (NUMJOKES - 1))
currentJoke = 0;
else
currentJoke++;
state = SENTKNOCKKNOCK;
} else {
theOutput = "Bye.";
state = WAITING;
}
}
return theOutput;
}
}
I think your problem is just both apps are waiting:
when KKServer starts, it waits for a client, and then it's waiting until the client "says" something, and the client is waiting until the server says something before waiting for the user input

Categories

Resources