Getting error : Exception in thread "main" java.net.SocketException: Socket closed - java

I am working on client-server chat program.
I have the two programs as follows:
client.java
import java.io.*;
import java.net.*;
import java.util.*;
class client {
public static void main(String[] args) throws IOException{
// ServerSocket SerSock = new ServerSocket(8090);
Socket cliSock = new Socket("localhost",8090);
BufferedReader in = new BufferedReader(new InputStreamReader(
cliSock.getInputStream()));
BufferedWriter out = new BufferedWriter( new OutputStreamWriter(
cliSock.getOutputStream()));
// out.write("some data".getBytes());
Scanner scan = new Scanner(System.in);
String message="";
message = in.readLine();
System.out.println(message);
// while((message = in.readLine()) != "bye")
// {
// System.out.println(message);
// System.out.println("I am in while in client");
// out.write(scan.nextLine());
// }
in.close();
out.close();
cliSock.close();
// SerSock.close();
}
}
server.java
import java.io.*;
import java.net.*;
import java.util.*;
class server {
public static void main(String[] args) throws IOException{
ServerSocket SerSock = new ServerSocket(8090);
System.out.println("Waiting for client...");
Socket cliSock = SerSock.accept();
// open();
// while ( !cliSock.isConnected())
// {
// }
BufferedReader in = new BufferedReader(new InputStreamReader(
cliSock.getInputStream()));
BufferedWriter out = new BufferedWriter( new OutputStreamWriter(
cliSock.getOutputStream()));
Scanner scan = new Scanner(System.in);
String message = "Hello client";
System.out.println(message);
out.write(message);
// while((message = in.readLine()) != "bye")
// {
// System.out.println("I am in while in server");
// System.out.println(message);
// message = scan.nextLine();
// out.write(message);
// }
in.close();
out.close();
cliSock.close();
SerSock.close();
}
}
Basically, I wanted to make a chat server program so that both can chat until they get bye message. I am unable to implement the program. The error is as follows:
Exception in thread "main" java.net.SocketException: Socket closed
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:121)
at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
at sun.nio.cs.StreamEncoder.implClose(StreamEncoder.java:316)
at sun.nio.cs.StreamEncoder.close(StreamEncoder.java:149)
at java.io.OutputStreamWriter.close(OutputStreamWriter.java:233)
at java.io.BufferedWriter.close(BufferedWriter.java:266)
at server.main(server.java:44)
I am novice in java. Please help me in solving the problem.

If you want to chat back and forth, stop closing your Input and Output Streams. Also, closing either stream on a Socket is equivalent to closing the Socket itself.
You should create a loop to keep reading new data from your Sockets
BufferedReader br = new BufferedReader(so.getInputStream());
while(true) {
String line = br.readLine();
...
}

If you are uncertain how to correctly use a class, or if an instance is behaving in a way you do not understand, then your first recourse should be to read the class's documentation.
If you had done so in this case, then you would have found that closing either the input stream or the output stream of a Socket closes the whole Socket. Your exception is being thrown when class server attempts to close a Sockets output stream after already closing its input stream. Note also that Socket.close() will close both streams, so you could just use that (only).

Related

Server's socket not outputting data unit client code stops running

I am playing around with networking and trying to send a simple message over my network using sockets in Java.
Here is the server code:
public class Server {
public static void main(String[] args) throws IOException {
String clientSentence;
String uppercaseSentence;
ServerSocket welcomeSocket = new ServerSocket(6789);
System.out.println("Server Running.");
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
clientSentence = inFromClient.readLine();
System.out.println("Client message received: " + clientSentence);
}
Here is the client code:
public class Client {
public static void main(String[] args) throws IOException {
String originalSentence;
String modifiedSentence;
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", 6789);
System.out.println("Please enter a sentence: ");
originalSentence = inFromUser.readLine();
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
outToServer.writeBytes(originalSentence);
System.out.println("Message Sent");
}
When I run them both and input a message into the client side, there is no confirmation on the side of the server in the console, however there is confirmation on the client side that a message has been sent. If I then end the client and stop it running, the server will output the sent message to the console them immediately throw an error.
I think it has something to do with the actual BufferedReader not actually getting the message or something?
Again I am very new to networking so any help would be much appreciated
Make sure that there is symmetry in how one connection sends data and how the other side receives the data. So, if the client is sending data via a DataOutputStream, then best to read the data in as a DataInputStream. If OTOH, you're only sending Strings, I would use a Writer such as a PrintWriter and then read with a Reader. I would send each line via println(...) and would call .flush() on the PrintWriter to ensure that the buffer sends the line when desired. For example, a simple client could look like so:
import java.util.*;
import java.net.*;
import java.io.*;
public class Client {
public static final String EXIT = "exit";
public static final int HOST_ID = 6789;
public static void main(String[] args) {
// using try-with-resources so that I close all streams when done
try (
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", HOST_ID);
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
) {
String input = "";
do {
System.out.print("Please enter a sentence, or \"exit\" to exit: ");
input = inFromUser.readLine();
out.println(input);
// flush the output stream to send all pending bites:
out.flush();
} while (!input.equalsIgnoreCase(EXIT));
System.out.println("All Done");
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
and the Server could look like:
import java.util.*;
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) {
// using try-with-resources so that I close all streams when done
try (
ServerSocket welcomeSocket = new ServerSocket(6789);
Scanner scanner = new Scanner(welcomeSocket.accept().getInputStream());
) {
System.out.println("Server Running.");
System.out.println("socket accepted");
while (scanner.hasNextLine()) {
String text = scanner.nextLine();
System.out.println("text: " + text);
System.out.println("uppercase: " + text.toUpperCase());
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}

Server and Client Interactions

Hello programmers on the internet. I am currently stepping through an operating systems book and there are some exercises that involve the following pieces of code.
This is the server code
import java.net.*;
import java.io.*;
public class DateServer{
public static void main(String[] args) {
try {
ServerSocket sock = new ServerSocket(6013);
// now listen for connections
while (true) {
Socket client = sock.accept();
PrintWriter pout = new
PrintWriter(client.getOutputStream(), true);
// write the Date to the socket
pout.println(new java.util.Date().toString());
// close the socket and resume
// listening for connections
client.close();
}
}
catch (IOException ioe) {
System.err.println(ioe);
}
}
}
This is the client code
import java.net.*;
import java.io.*;
public class DateClient{
public static void main(String[] args) {
try {
//make connection to server socket
Socket sock = new Socket("127.0.0.1",6013);
InputStream in = sock.getInputStream();
BufferedReader bin = new
BufferedReader(new InputStreamReader(in));
// read the date from the socket
String line;
while ( (line = bin.readLine()) != null)
System.out.println(line);
// close the socket connection
sock.close();
}
catch (IOException ioe) {
System.err.println(ioe);
}
}
}
So to my understanding the server is creating a socket and writing a date value to it. The client is then coming a long and connecting to the server and writing out the value in that socket. Am I interpreting this code correctly? This is my first experience with sockets.
Now for my actual question. I want to have the client connect to the server (and print out a message saying you are connected) and then be able to send a value over to the server so that the server can process it. How would I go about doing this? I have tried tinkering with DataOutputStream and DataInputStream but I have never used either before. Any help would be GREATLY appreciated.
You are correct. You have the server writing to the socket and the client reading from the socket. You want to reverse that.
Server Should look like:
ServerSocket sock = new ServerSocket(6013);
// now listen for connections
while (true)
{
Socket client = sock.accept();
InputStream in = client.getInputStream();
BufferedReader bin = new BufferedReader(new InputStreamReader(in));
// read the date from the client socket
String line;
while ((line = bin.readLine()) != null)
System.out.println(line);
// close the socket connection
client.close();
}
The client should look like:
try
{
// make connection to server socket
Socket sock = new Socket("127.0.0.1", 6013);
PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
// send a date to the server
out.println("1985");
sock.close();
}
catch (IOException ioe)
{
System.err.println(ioe);
}

How to make socket communications?

Recently I was looking at socket communications, and after I read few tutorials I came out with something like that.
public class Server{
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket server = new ServerSocket(9999);
Socket socket = server.accept();
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String message = "";
int ch = -1;
while((ch=in.read())!= -1 ){
message+=ch;
}
// String message = in.readLine();
System.out.println("RECEIVED "+message);
out.write("RESPONSE "+message+"\n");
out.flush();
System.out.println("NEW MESSAGE SEND");
Thread.sleep(3000);
System.out.println("CLOSE");
server.close();
}
}
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket = new Socket("127.0.0.1", 9999);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.write("MESSAGE\n");
out.flush();
System.out.println("SEND MESSAGE");
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println(in.readLine());
socket.close();
}
}
After I run this code, Client logs "SEND MESSAGE" while server hangs on in.read() and does not receiving any message.
Can anyone help me and explain me what I'm doing wrong?
Your server is reading from the socket until end of stream. End of stream only occurs when the peer closes the connection. At that point you will be unable to send a reply. You need to reconsider your protocol. For a simple example you could read and write lines, one at a time, as you are in the client.

remote java console application control using cmd

I have Java console app, which i want to control from another computer. I use Socket class to send data through net and pipeline to connect the remote controlled program with Sender and Reader program, as shown:
Reader:
import java.io.*;
import java.net.*;
public class Reader {
//reads information from the remote controlled program
public static void main(String[] args) throws Exception {
Socket s = new Socket(args[0], Integer.parseInt(args[1]));
PrintWriter bw = new PrintWriter(s.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String vstup;
do {
vstup = in.readLine();
if(vstup==null) break;
bw.println(vstup);
} while(true);
s.close();
}
}
Sender:
import java.io.*;
import java.net.*;
public class Sender {
//sends instruction to the remote controlled program
public static void main(String[] args) throws Exception {
Socket s = new Socket(args[0], Integer.parseInt(args[1]));
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
String vstup;
do {
vstup = in.readLine();
if(vstup==null) break;
System.out.println(vstup);
} while(true);
s.close();
}
}
RemoteController:
import java.net.*;
import java.io.*;
public class RemoteController {
public static void main(String[] main) throws IOException {
ServerSocket ss = new ServerSocket(Integer.parseInt(main[0]));
System.out.println("Done, please connect the program.");
Socket reader = ss.accept(); //reads what the program says
System.out.println("reader connected");
Socket writer = ss.accept(); //writes into the program
System.out.println("writer connected");
BufferedReader read = new BufferedReader(new InputStreamReader(reader.getInputStream()));
PrintWriter write = new PrintWriter(writer.getOutputStream(), true);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
for(int i = 0; i<5; i++) {
write.println(br.readLine());
System.out.println(read.readLine());
}
write.close();
read.close();
writer.close();
reader.close();
ss.close();
}
}
now i run the Remote controller and then i write
java Sender localhost 1234 | java SomeProgram | java Reader localhost 1234
into a comand prompt to test whenever it works. It sometimes works, sometimes not, any advise how to make it work everytime?
All the problem was that the Sender and Reader programms conected in a random order to the main program, so adding Thread.sleep(200) resolved my problem, sorry for annoying.
PS: If you program in java (and cmd), try it, iƄ really fun i think.

why doesn't my client read correctly the outputStream sent by the Server?

It's a simple client-server where Server using a BufferedWriter object would send to the Client receiving in the object BufferedReader.
When I use OutputStream and PrintWriter for the Server and InputStream and Scanner for the Client it works well.
What happens is that the client in Buffered way reads -1 if I'm sending an int and null for String.
I hope my English makes sense. ;P
That's the code:
Server:
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8189);
Socket incoming;
incoming = server.accept();
try {
// OutputStream output = incoming.getOutputStream();
// PrintWriter outStream = new PrintWriter(output, true /*autoFlush*/);
// outStream.println("ENTER");
BufferedWriter output = new BufferedWriter(new
OutputStreamWriter(incoming.getOutputStream()));
output.write(3);
System.out.println("\nSent");
} finally {
incoming.close();
}
}
}
Client:
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//Client theClient= new Client();
Socket RTSPSocket;
int ServerPort = 8189;
//server name address
String ServerHost = "localhost";
//get Server IP Address
InetAddress ServerIPAddress = InetAddress.getByName(ServerHost);
RTSPSocket = new Socket(ServerIPAddress, ServerPort);
try {
/*
InputStream input = theClient.RTSPSocket.getInputStream();
Scanner in = new Scanner(input);
String line = in.nextLine();
System.out.println(line);
*/
BufferedReader input = new BufferedReader(new
InputStreamReader(RTSPSocket.getInputStream()));
//String line = input.readLine();
//System.out.println("\nRicevuto: " + line);
System.out.println(input.read());
} catch (Exception e) {
System.err.println("Error: " + e);
}
}
}
try putting the following code after output.write(3);
output.flush();
The BufferedOutputStream is built to only send the data when the buffer is full (I believe the default 1024 bytes). So, to force the data to be sent you need to flush the stream.
You have to flush data to receive them in the client part.
output.write(3);
output.flush();
System.out.println("\nSent");
When you have an OutputStream (or a Writer) you have to flush your data, this way you're 100% sure that what you wanted to be send has been sent.
Most (if not all) the OutputStream subclasses use a "mini buffer" which is flushed only when it's full or you manually call flush(). In your case, it's even more flagrant because you're using a BufferedWriter.
Another thing, when you use streams/writers, you really should close them after you're finished, one of the main thing close() do (most of the time) is flushing the last data remaining in the "mini buffer".
Resources :
Javadoc - OutputStream.flush()

Categories