Java IOException Stream Closed in Server Client program - java

I am trying to make a Server Client program that allows sending multiple messages from server to client or vice versa without waiting for a response. The program works fine when the first client is connected and disconnected. But when I connect the client again, I get the error. Here is my server code:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.io.InputStreamReader;
import java.io.BufferedReader;
class Q2Server implements Runnable{
private ServerSocket serverSocket;
private Socket socket;
private DataOutputStream out;
private BufferedReader in1;
private DataInputStream in2;
private Thread read, write;
private String clientMsg, serverMsg;
public Q2Server (int port) throws IOException{
serverSocket = new ServerSocket(port);
while(true) {
try {
System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
socket = serverSocket.accept();
System.out.println("Just connected to " + socket.getRemoteSocketAddress());
out = new DataOutputStream(socket.getOutputStream());
out.writeUTF("Thanks for connecting to " + socket.getLocalSocketAddress());
clientMsg = "";
serverMsg = "";
read = new Thread(this);
write = new Thread(this);
read.start();
write.start();
read.join();
write.join();
} catch(IOException e) {
e.printStackTrace();
} catch(InterruptedException ie) {
ie.printStackTrace();
}
}
}
public void run () {
try {
if(Thread.currentThread() == write) {
while(true) {
try {
if(clientMsg.equals("close")) {
break;
} else {
in1 = new BufferedReader(new InputStreamReader(System.in));
out = new DataOutputStream(socket.getOutputStream());
serverMsg = in1.readLine();
out.writeUTF(serverMsg);
if(serverMsg.equals("close")) {
socket.close();
in1.close();
in2.close();
out.close();
System.out.println("Closing connection...");
break;
}
}
} catch (SocketException s) {
break;
}
}
} else {
while(true) {
try {
if(serverMsg.equals("close")) {
break;
}
in2 = new DataInputStream(socket.getInputStream());
clientMsg = in2.readUTF();
System.out.println("Client: " + clientMsg);
if(clientMsg.equals("close")) {
socket.close();
in1.close();
in2.close();
out.close();
System.out.println("Closing connection...");
break;
}
} catch(SocketException s) {
break;
}
}
}
} catch (IOException i) {
i.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
Q2Server server = new Q2Server(8080);
}
}
Client code:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.rmi.UnexpectedException;
import java.io.InputStreamReader;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.lang.Thread;
class Q2Client implements Runnable {
private Socket socket;
private Thread read, write;
private BufferedReader in1;
private DataInputStream in2;
private DataOutputStream out;
private String clientMsg, serverMsg;
public Q2Client(int port) {
try {
socket = new Socket("localHost",port);
System.out.println("Connected to port: " + port);
clientMsg = serverMsg = "";
read = new Thread(this);
write = new Thread(this);
in2 = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
System.out.println(in2.readUTF());
read.start();
write.start();
read.join();
write.join();
} catch(UnexpectedException u) {
u.printStackTrace();
} catch(IOException i) {
i.printStackTrace();
} catch(InterruptedException ie) {
ie.printStackTrace();
}
}
public void run() {
try {
if(Thread.currentThread() == write) {
while(true) {
try {
if(serverMsg.equals("close")) {
break;
}
in1 = new BufferedReader(new InputStreamReader(System.in));
out = new DataOutputStream(socket.getOutputStream());
clientMsg = in1.readLine();
out.writeUTF(clientMsg);
if(clientMsg.equals("close")) {
socket.close();
in1.close();
in2.close();
out.close();
System.out.println("Closing connection...");
break;
}
} catch (SocketException s) {
break;
}
}
} else {
while(true) {
try {
if(clientMsg.equals("close")) {
break;
}
in2 = new DataInputStream(socket.getInputStream());
serverMsg = in2.readUTF();
System.out.println("Server: " + serverMsg);
if(serverMsg.equals("close")) {
socket.close();
in1.close();
in2.close();
out.close();
System.out.println("Closing connection...");
break;
}
} catch (SocketException s) {
break;
}
}
}
} catch (IOException i) {
i.printStackTrace();
}
}
public static void main(String[] args) {
Q2Client client = new Q2Client(8080);
}
}
Here is the stacktrace of the exception:
java.io.IOException: Stream closed
at java.base/java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:176)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:342)
at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.base/java.io.InputStreamReader.read(InputStreamReader.java:185)
at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
at Q2Server.run(Q2Server.java:65)
at java.base/java.lang.Thread.run(Thread.java:835)
When either of the server or client sends "close" the connection closes. The client can connect again. But when I run the client code again, I get the exception. What is going wrong and how do I fix this?

You're getting an exception because you're trying to read from a BufferedReader which no longer exists, the in1 in particular. At the first run, all your streams and readers open as they should, but after getting the command close from the client, your server closes the in1. Then, when the client tries to reconnect, the program tries to assign the value of in1.readLine() to serverMsg which is a String, but since in1 is no more, the IOException occurs since the BufferedReader is closed and nothing can be read from it.
I suppose since you want to leave the server running while the client(s) can connect and disconnect at any given time, which totally makes sense, maybe you shouldn't close the BufferedReader which supplies keyboard commands to the server in your case. Closing it doesn't make sense to me, since you're not stopping the whole server when the client disconnects, you just close the connection, but the server still should be able to accept commands.
Hope this helps.

Related

Socket Programming Implementation Using Threading in Java [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 months ago.
Improve this question
Here I can solve socket programming for chat application between multiple client and server where client can send multiple message to the server. But now I want to solve a new problem where conversion of any string from any client [each client can send at most 2 messages] into a FULL UPPERCASE string with the help of the server. The server will be able to serve at most 5 clients.
This is my client coe.....
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws IOException {
System.out.println("Client started..");
Socket socket = new Socket("127.0.0.1", 22222);
System.out.println("Client Connected..");
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
while (true) {
Scanner sc = new Scanner(System.in);
String message = sc.nextLine();
if(message.equals("exit")){
break;
}
//sent to server...
oos.writeObject(message);
try {
//receive from server..
Object fromServer = ois.readObject();
System.out.println("From Server: " + (String) fromServer);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
socket.close();
}
}
This is my server code........
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(22222);
System.out.println("Server Started..");
while (true) {
Socket socket = serverSocket.accept();
System.out.println("Client connected..");
// new Server Thread Start.....
new ServerThread(socket);
}
}
}
class ServerThread implements Runnable {
Socket clientSocket;
Thread t;
ServerThread(Socket clientSocket) {
this.clientSocket = clientSocket;
t = new Thread(this);
t.start();
}
#Override
public void run() {
try {
ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream());
while (true) {
//read from client...
Object cMsg = ois.readObject();
if (cMsg == null)
break;
System.out.println("From Client: " + (String) cMsg);
String serverMsg = (String) cMsg;
serverMsg = serverMsg.toUpperCase();
//send to client..
oos.writeObject(serverMsg);
}
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Sever side
package sockettreading;
import java.io.*;
import java.net.*;
/**
*
* #author Amanur Rahman
*/
public class SocketTreading {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(5050);
System.out.println("Server is starting...");
int cn=1;
while (cn<=5) {
Socket s = ss.accept();
System.out.println("Client"+cn+" is connected \n" + s);
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
System.out.println("Assinging new thread for this client");
Thread t = new ClientHandler(s, dis, dos);
t.start();
cn++;
}
System.out.println("Client limit cross");
ss.close();
}
}
class ClientHandler extends Thread {
final Socket soc;
final DataInputStream input;
final DataOutputStream output;
int i = 1;
public ClientHandler(Socket s, DataInputStream dis,
DataOutputStream dos) {
this.soc = s;
this.input = dis;
this.output = dos;
}
#Override
public void run() {
String received;
String ends;
String toreturn;
while (i <= 2) {
try {
output.writeUTF("Please write your message : ");
String str = input.readUTF();
System.out.println("Client msg is: "+ str.toUpperCase());
output.writeUTF("Do you want to exit or continue ( if exit type \"ENDS\" ) ");
ends = input.readUTF();
if (ends.equals("ENDS")) {
System.out.println("Client" + this.soc + "send exit.");
this.soc.close();
System.out.println("Connection closed");
break;
}
} catch (IOException e) {
System.out.println(e);
}
System.out.println("" + i);
i++;
}
try {
this.input.close();
this.output.close();
} catch (IOException e) {
System.out.println(e);
}
}
}
// client side
package sockettreading;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
/**
*
* #author Amanur Rahman
*/
public class ClientThreading {
public static void main(String[] args) throws IOException {
try(Socket s = new Socket("localhost", 5050);){
System.out.println("Connected");
Scanner scn = new Scanner(System.in);
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
DataInputStream dis = new DataInputStream(s.getInputStream());
int i = 1;
while (i <= 2) {
System.out.println(dis.readUTF());
String num1 = scn.nextLine();
dos.writeUTF(num1);
System.out.println(dis.readUTF());
String num2 = scn.nextLine();
dos.writeUTF(num2);
System.out.println(dis.readUTF());
String ends = scn.nextLine();
dos.writeUTF(ends);
if (ends.equals("ENDS")) {
System.out.println("Closing the connection" + s);
s.close();
System.out.println("Connection closed");
break;
}
i++;
}
System.out.println(dis.readUTF());
s.close();
dos.close();
dis.close();
}
catch (IOException ex) {
if(ex.getMessage()!=null){
System.out.println("Already 5 clients are served so the server is closed: ");
}else{
System.out.println("Client 2 message already send. That's way the connection closed.");
}
}
}
}

Java Concurrent Socket Programming

Below is my code for a simple Concurrent Server. Whenever I run multiple clients, the server only prints out the input of the first client. I'm not sure what I've done wrong. Any help would be appreciated.
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8001);
while (true){
Socket clientSocket = serverSocket.accept();
System.out.println(clientSocket);
ConcurrentServer client = new ConcurrentServer(clientSocket);
client.start();
}
} catch (IOException i){}
}
public void run(){
try {
inputStream = new BufferedReader(new InputStreamReader(concurrentSocket.getInputStream()));
outputStream = new PrintWriter(new OutputStreamWriter(concurrentSocket.getOutputStream()));
String testString = inputStream.readLine();
System.out.println(testString);
} catch (IOException i){}
}
This code might help you to understand how to run multiple clients concurrently. :)
What this code does? TCP Client sends a string to the server and TCP server sends back the string in UPPERCASE format & the server can do this concurrently with multiple connections.
I have included 3 files for the server and one more for testing the server with multiple clients(ClientTest.java)
Main.java
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
new Server(3000).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server.java
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Logger;
public class Server {
private ServerSocket sSocket;
private boolean run;
private int port;
public Server(int port) throws IOException {
this.port = port;
this.sSocket = new ServerSocket(this.port);
}
public void start() {
this.run = true;
Logger.getLogger(getClass().getName()).info("Server is listening on port: " + port);
try {
while (run) {
Socket cs = sSocket.accept();
Logger.getLogger(getClass().getName())
.info("New Client Connected! " + cs.getPort());
new Thread(new Client(cs)).start(); // Put to a new thread.
}
} catch (IOException e) {
Logger.getLogger(getClass().getName()).severe(e.getMessage());
}
}
public void stop() {
this.run = false;
}
}
Client.java (Client Process on server)
import java.io.*;
import java.net.Socket;
import java.util.logging.Logger;
public class Client implements Runnable {
private Socket clientSocket;
private DataOutputStream out; // write for the client
private BufferedReader in; // read from the client
public Client(Socket clientSocket) {
this.clientSocket = clientSocket;
}
#Override
public void run() {
// Do client process
outToClient(inFromClient().toUpperCase());
closeConnection();
}
private String inFromClient() {
String messageFromClient = "";
/*
* Do not use try with resources because once -
* - it exits the block it will close your client socket too.
*/
try {
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
messageFromClient = in.readLine();
} catch (IOException e) {
Logger.getLogger(getClass().getName()).severe("InFromClientErr - " + e.getMessage());
}
return messageFromClient.trim().equals("") ? "No Inputs given!" : messageFromClient;
}
private void outToClient(String message) {
try {
out = new DataOutputStream(clientSocket.getOutputStream());
out.writeBytes(message);
} catch (IOException e) {
Logger.getLogger(getClass().getName()).severe("OutToClientErr - " + e.getMessage());
}
}
private void closeConnection() {
try {
in.close();
out.close();
clientSocket.close();
} catch (NullPointerException | IOException e) {
Logger.getLogger(getClass().getName()).severe(e.getMessage());
}
}
}
ClientTest.java (For Testing clients)
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class ClientTest {
public static void main(String[] args) {
Socket clientSocket;
try {
clientSocket = new Socket("localhost", 3000);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
outToServer.writeBytes(new Scanner(System.in).nextLine() + '\n'); // Get user input and send.
System.out.println(inFromServer.readLine()); // Print the server response.
} catch (IOException e) {
e.printStackTrace();
}
}
}
The issue was instead with the client. Not the server. The socket was declared outside of the for loop, and therefore only one connection was being created. Like so below:
public static void main(String[] args) {
try {
socket = new Socket("127.0.0.1", 8001);
for (int i = 0; i < 5; i++){
System.out.println("Starting client: " + i);
ConcurrentClient concurrentClient = new ConcurrentClient(socket, i);
concurrentClient.run();
}
} catch (IOException io) {
}
}
The Socket should be declared inside the for loop like so:
public static void main(String[] args) {
try {
for (int i = 0; i < 5; i++){
socket = new Socket("127.0.0.1", 8001);
System.out.println("Starting client: " + i);
ConcurrentClient concurrentClient = new ConcurrentClient(socket, i);
concurrentClient.run();
}
} catch (IOException io) {
}
}
I really don't know why you need so complex structure of input and output streams. It is better to use Scanner that will wait for the new input.
Also you can use PrintWriter to output the results of your conversation.
Here is server that accepts multiple clients:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class ConcurrentServer extends Thread {
private Socket concurrentSocket;
public ConcurrentServer(Socket clientSocket) {
this.concurrentSocket = clientSocket;
}
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8001);
while (true){
Socket clientSocket = serverSocket.accept();
System.out.println(clientSocket);
ConcurrentServer client = new ConcurrentServer(clientSocket);
client.start();
}
} catch (IOException i){}
}
public void run(){
try {
InputStream inputStream = concurrentSocket.getInputStream();
Scanner scanner = new Scanner(inputStream);
OutputStream outputStream = concurrentSocket.getOutputStream();
PrintWriter pw = new PrintWriter(outputStream);
while(scanner.hasNextLine()){
String line = scanner.nextLine();
System.out.println(line);
pw.println("message: " + line);
pw.flush();
}
} catch (IOException i){}
}
}

Java Socket Server won't process second client

I've got a client and server coded in Java, once the server has received one message from the client, the server stops receiving all new messages. No errors are thrown when the client tries to sent more messages. I can't seem to find out why it doesn't allow or receive new connections! Please help.
public class Server implements Runnable {
#Override
public void run() {
ServerSocket echoServer = null;
String line;
DataInputStream is;
PrintStream os;
Socket clientSocket = null;
boolean Listening = true;
int sPort = 9999;
// Try to open a server socket on port 9999
try {
echoServer = new ServerSocket(sPort);
}
catch (IOException e) {
System.out.println(e);
}
// Create a socket object from the ServerSocket to listen and accept
// connections.
// Open input and output streams
while (Listening){
try {
clientSocket = echoServer.accept();
is = new DataInputStream(clientSocket.getInputStream());
//os = new PrintStream(clientSocket.getOutputStream());
// As long as we receive data, echo that data back to the client.
while (true) {
line = is.readLine();
if(line != null){
//os.println(line);
log(Level.SEVERE, "New connection to server {0}", line);
}
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
while (true)
{
line = is.readLine();
if(line != null){
//os.println(line);
log(Level.SEVERE, "New connection to server {0}", line);
}
}
after accepting a connection it is entering into this infinite loop.due to this loop it will never accept new connection.
to solve this issues, start new thread each time when new client comes, pass socket connection of the client and read data from that client.
I see two issues as below:
while (true) {
line = is.readLine();
if(line != null){
//os.println(line);
log(Level.SEVERE, "New connection to server {0}", line);
}
Here you need to break after reading the content from the Socket irrespective of whether you read in different thread or same.
You need to declare boolean Listening to volatile else the server wont stop.
while (true) {
line = is.readLine();
if(line != null){
//os.println(line);
log(Level.SEVERE, "New connection to server {0}", line);
}
}
the code will block new request, so the second request will not be accepted.
I make an example accounding to your code. Hope it help to you.
The Server Class will only be userd to accept socket connection and create a new thread to process it.
import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Server implements Runnable {
#Override
public void run() {
ServerSocket echoServer = null;
boolean listening = true;
Socket clientSocket = null;
int sPort = 9999;
// Try to open a server socket on port 9999
try {
echoServer = new ServerSocket(sPort);
} catch (IOException e) {
System.out.println(e);
}
// Create a socket object from the ServerSocket to listen and accept
// connections.
// Open input and output streams
while (listening) {
try {
clientSocket = echoServer.accept();
System.out.println("receive new connection");
new ProcessClientThread(clientSocket).start();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE,
null, ex);
}
}
}
}
The ProcessClientThread Class extends Thread Class and defined a constructor with a Socket type parameter. Override run method of it. The run method get input stream from socket and print it out. When it accept 0, it will close the scoket connection. Its code like this
import java.io.DataInputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;
public class ProcessClientThread extends Thread {
Socket socket = null;
public ProcessClientThread(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
DataInputStream is;
String line;
boolean flag = true;
try {
is = new DataInputStream(socket.getInputStream());
while (flag) {
line = is.readLine();
if (Integer.valueOf(line) != 0) {
// os.println(line);
// Logger.getLogger(Level.SEVERE,
// "New connection to server {0}", line);
System.out.println(line);
} else {
Writer w = new OutputStreamWriter(socket.getOutputStream());
w.write(0);
w.flush();
flag = false;
socket.close();
System.out.println("close a connection");
}
}
} catch(Exception e) {
}
}
}
There is a StartUp Class which used to start up the server thread.
public class StartUp {
public static void main(String[] args) {
new Thread(new Server()).start();
}
}
Run the below Client Class to test the Server.
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws Exception {
Socket client = new Socket("localhost", 9999);
OutputStreamWriter writer = new OutputStreamWriter(client.getOutputStream());
Reader reader = new InputStreamReader(System.in);
Reader serverReader = new InputStreamReader(client.getInputStream());
boolean flag = true;
while(flag) {
int readContent = reader.read();
writer.write(readContent);
writer.flush();
if(readContent == 0) {
writer.close();
client.close();
flag = false;
}
}
}
}

Java socket - simple program doesn't work

I've spent lot of time to find out where is the problem but with no success. Server is launching correctly, but when I launch Client I get "Unexpected Error" exception. I've changed ports too with no effects. What should I do to make this working?
/* Server.java */
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 Server
{
private static final int PORT = 50000;
static boolean flaga = true;
private static ServerSocket serverSocket;
private static Socket clientSocket;
public static void main(String[] args) throws IOException
{
serverSocket = null;
try
{
serverSocket = new ServerSocket(PORT);
}
catch(IOException e)
{
System.err.println("Could not listen on port: "+PORT);
System.exit(1);
}
System.out.print("Wating for connection...");
Thread t = new Thread(new Runnable()
{
public void run()
{
try
{
while(flaga)
{
System.out.print(".");
Thread.sleep(1000);
}
}
catch(InterruptedException ie)
{
//
}
System.out.println("\nClient connected on port "+PORT);
}
});
t.start();
clientSocket = null;
try
{
clientSocket = serverSocket.accept();
flaga = false;
}
catch(IOException e)
{
System.err.println("Accept failed.");
t.interrupt();
System.exit(1);
}
final PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),true);
final BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
t = new Thread(new Runnable()
{
public void run()
{
try
{
Thread.sleep(5000);
while(true)
{
out.println("Ping");
System.out.println(System.currentTimeMillis()+" Ping sent");
String input = in.readLine();
if(input.equals("Pong"))
{
System.out.println(System.currentTimeMillis()+" Pong received");
}
else
{
System.out.println(System.currentTimeMillis()+" Wrong answer");
out.close();
in.close();
clientSocket.close();
serverSocket.close();
break;
}
Thread.sleep(5000);
}
}
catch(Exception e)
{
System.err.println(System.currentTimeMillis()+" Unexpected Error");
}
}
});
t.start();
}
}
and the Client class
/* Client.java */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Client
{
private static final int PORT = 50000;
private static final String HOST = "localhost";
public static void main(String[] args) throws IOException
{
Socket socket = null;
try
{
socket = new Socket(HOST, PORT);
}
catch(Exception e)
{
System.err.println("Could not connect to "+HOST+":"+PORT);
System.exit(1);
}
final PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
final BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Thread t = new Thread(new Runnable()
{
public void run()
{
long start = System.currentTimeMillis();
while (true)
{
try
{
String input = in.readLine();
if (input != null)
{
System.out.println(System.currentTimeMillis() + " Server: " + input);
}
if (input.equals("Ping"))
{
if(System.currentTimeMillis()-start>30000)
{
out.println("Pon g");
System.out.println(System.currentTimeMillis() + " Client: Pon g");
break;
}
out.println("Pong");
System.out.println(System.currentTimeMillis() + " Client: Pong");
}
}
catch (IOException ioe)
{
//
}
}
}
});
t.start();
out.close();
in.close();
socket.close();
}
}
Here is the output on running
Wating for connection............
Client connected on port 50000
1368986914928 Ping sent
java.lang.NullPointerException
at Server$2.run(Server.java:84)
at java.lang.Thread.run(Thread.java:722)
You're making a big mistake with those catch blocks that are empty or print out your useless message.
You'll get more information if you print or log the stack trace. It's simply a must.
You need some intro instruction - have a look at this and see how it's different from yours.
http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html
It shows your out object is null. Instead of input.equals("Pong") use input != null && input.equals("Pong") in line 84 of Server.java. I guess you would have received Pong received but in later stages when you are listening to nothing you could have got this NPE.

Socket in multithreading "deadlocked" Java

I am trying to launch server and client thread on the same process, but seems like the server thread is blocking the client thread (or vice versa). I'm not allowed to use any global variable between those threads(like semaphore or mutex, since the client and the server thread are launched by upper-class that I don't have the access of).
I found a similar question here , but it still use two different process (two main function).
Here is a sample of my code
The server code:
public class MyServer implements Runnable{
ServerSocket server;
Socket client;
PrintWriter out;
BufferedReader in;
public MyServer() throws IOException{
server = new ServerSocket(15243, 0, InetAddress.getByName("localhost"));
}
#Override
public void run() {
while(true){
try {
ArrayList<String> toSend = new ArrayList<String>();
System.out.println("I'll wait for the client");
client = server.accept();
out = new PrintWriter(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String inputLine;
while((inputLine = in.readLine()) != null){
toSend.add("answering : "+inputLine);
}
for(String resp : toSend){
out.println(resp);
}
client.close();
out.close();
in.close();
} catch (IOException ex) {
}
}
}
}
And the client code:
public class MyClient implements Runnable{
Socket socket;
PrintWriter out;
BufferedReader in;
public MyClient(){
}
#Override
public void run() {
int nbrTry = 0;
while(true){
try {
System.out.println("try number "+nbrTry);
socket = new Socket(InetAddress.getByName("localhost"), 15243);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.println("Hello "+nbrTry+" !! ");
String inputLine;
while((inputLine = in.readLine()) != null){
System.out.println(inputLine);
}
nbrTry++;
} catch (UnknownHostException ex) {
} catch (IOException ex) {
}
}
}
}
And the supposed upper-class launching those thread:
public class TestIt {
public static void main(String[] argv) throws IOException{
MyServer server = new MyServer();
MyClient client = new MyClient();
(new Thread(server)).start();
(new Thread(client)).start();
}
}
It gives me as output:
I'll wait for the client
Try number 0
And it stuck here. What should I do to keep both server and client code running?
Thank you.
I'll be willing to take up your questions but basically you need to think through your logic a bit more carefully.
MyServer.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer implements Runnable {
ServerSocket server;
public MyServer() throws IOException {
server = new ServerSocket(15243, 0, InetAddress.getByName("localhost"));
}
#Override
public void run() {
while (true) {
try {
// Get a client.
Socket client = server.accept();
// Write to client to tell him you are waiting.
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
out.println("[Server] I'll wait for the client");
// Let user know something is happening.
System.out.println("[Server] I'll wait for the client");
// Read from client.
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String inputLine = in.readLine();
// Write answer back to client.
out.println("[Server] Answering : " + inputLine);
// Let user know what it sent to client.
System.out.println("[Server] Answering : " + inputLine);
in.close();
out.close();
client.close();
} catch (Exception e) {
}
}
}
}
MyClient.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class MyClient implements Runnable {
Socket socket;
PrintWriter out;
BufferedReader in;
public MyClient() throws UnknownHostException, IOException {
}
#Override
public void run() {
int nbrTry = 0;
while (true) {
try {
// Get a socket
socket = new Socket(InetAddress.getByName("localhost"), 15243);
// Wait till you can read from socket.
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String inputLine = in.readLine();
//inputLine contains the text '[Server] I'll wait for the client'. means that server is waiting for us and we should respond.
// Write to socket
out = new PrintWriter(socket.getOutputStream(), true);
out.println("[Client] Hello " + nbrTry + " !! ");
// Let user know you wrote to socket
System.out.println("[Client] Hello " + nbrTry++ + " !! ");
} catch (UnknownHostException ex) {
} catch (IOException ex) {
}
}
}
}
TestIt.java
import java.io.IOException;
public class TestIt {
public static void main(String[] argv) throws IOException {
MyServer server = new MyServer();
MyClient client = new MyClient();
(new Thread(server)).start();
(new Thread(client)).start();
}
}
Your client sends a string, then reads until the stream is exhausted:
while((inputLine = in.readLine()) != null){
BufferedReader.readLine() only returns null at the end of the stream, as I recall. On a stream, it will block until input is available
Your server receives until the stream is exhausted, then sends back its response.
After sending one line, you now have:
Your client waiting for a response.
Your server still waiting for more data from the client. But it doesn't send anything back until the end of the stream from the client (which never happens because the client is waiting for your response).

Categories

Resources