EOFException in java networking - java

it is my first time using java networking. I have to use it for a project i am working on which is a simple card game. My server and client will communicate as the "Connection Received" does get printed. But after this line the following error occurs:
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at ClientConnectionManager.reciveData(ClientConnectionManager.java:49)
at LogicThread.getHandSize(GameLogic.java:22)
at LogicThread.run(GameLogic.java:16)
at java.lang.Thread.run(Unknown Source)
Exception in thread "Thread-4" java.lang.NullPointerException
at LogicThread.getHandSize(GameLogic.java:22)
at LogicThread.run(GameLogic.java:16)
at java.lang.Thread.run(Unknown Source)
the classes in question are:
static ObjectInputStream input;
static ObjectOutputStream output;
static Socket socket;
public static void connectToServer(){
try {
System.out.println("connecting");
socket = new Socket(ip, port);
input = new ObjectInputStream(socket.getInputStream());
output = new ObjectOutputStream(socket.getOutputStream());
output.flush();
System.out.println("connected");
reciveData();
logic.startLogic();
//listenForData();
} catch (IOException e) {
e.printStackTrace();
}
}
public static Object reciveData(){
try {
Object obj = input.readObject(); - Error is on this line
System.out.println(obj);
return obj;
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
return null;
}
The server code for sending data:
ServerSocket server;
server = new ServerSocket(2302);
Socket connection;
connection = server.accept();
output = new ObjectOutputStream(connection.getOutputStream());
public void sendData(Object data){
try {
output.writeObject(data);
output.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
I am not sure what causes this because the server sends a "Connection Received" which the client receives with no issue and prints. But any call from outside the connectToServer() Method cause the error above.

The peer has closed the connection. Somewhere the server is closing the accepted socket or one of its streams.
That implies that if the server has really called sendData() it must have thrown an exception you haven't mentioned.

Related

In Client server socket program, getting socket exception when input stream is not read by clientsocket

In the client-server socket program below, the client is sending data to server which is listening on port 3500, but here the server is not sending any data back to client, so in the client socket program, i do not read from then input stream then am getting socket exception, socket write error.
below is the server code:
private static ServerSocket sc = null;
private static final int port = 3500;
public static void main(String args[]) throws IOException{
try {
sc = new ServerSocket(port);
while(true){
Socket socket = sc.accept();
System.out.println("Listening on port <=> "+port);
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
String message = (String) ois.readObject();
System.out.println("Received Request <=>"+message);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject("Hi Client received your message<=>"+message);
ois.close();
oos.close();
socket.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Client socket code below:
try {
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
Socket clientsocket = null;
for(int i=0;i<2;i++){
clientsocket = new Socket(InetAddress.getLocalHost().getHostName(), 3500);
oos = new ObjectOutputStream(clientsocket.getOutputStream());
oos.writeObject("Client Request: "+i);
//ois = new ObjectInputStream(clientsocket.getInputStream());
//String message = (String) ois.readObject();
//System.out.println("Message sent by Server: " + message);
//ois.close();
oos.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
In the above code, if the comments are removed then the code is working fine, but confused why the input stream should be read when there is no data to be read.
Getting below exception after commenting the input stream section as done above.
Listening on port <=> 3500
Received Request <=>Client Request: 0
java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(Unknown Source)
at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(Unknown Source)
at java.io.ObjectOutputStream.writeNonProxyDesc(Unknown Source)
at java.io.ObjectOutputStream.writeClassDesc(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeFatalException(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at com.springexercise.demo.ServerTest.main(ServerTest.java:28)
The error is because you close the connection on the client side before the server has a chance to write data into the stream.
If you remove the
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject("Hi Client received your message<=>"+message);
....
oos.close();
part the error should be resolved because the server is no longer trying to write on a closed connection.
If you have the client reading part in the code the whole process works because the client wait for new data in the connection. That leads to the situation where the connection is still open when the server tries to write and everything is working as expected from the java site.

Socket closed as soon as passed into new thread

I am trying to create a multi-threaded duplex chat server. I had it working fine before I moved the code into threads, but now I'm getting "SocketException: Socket is closed" whenever a thread tries to access a socket.
My teacher and I can't figure it out. (teacher knows even less Java than I do; he is a C guy). It seems like the socket is open, but as soon as it goes into the thread, it is closed.
What am I doing wrong?
Client code:
public class Client {
public static void main(String[] args) throws IOException {
String hostName = "localhost";
int portNumber = 6969;
try (
Socket socket = new Socket(hostName, portNumber);
) {
System.out.println("Chat connected");
//Sender
if (!socket.isClosed())
new Thread(new Sender(socket)).start();
//Receiver
if (!socket.isClosed())
new Thread(new Receiver(socket)).start();
} catch (SocketException e) {
System.out.println("Connection terminated unexpectedly");
}
}
}
Server code:
public class Server {
public static void main(String[] args) throws IOException {
int portNumber = 6969;
try (
ServerSocket serverSocket = new ServerSocket(portNumber);
Socket clientSocket = serverSocket.accept();
) {
//Receiver
if (!clientSocket.isClosed())
new Thread(new Receiver(clientSocket)).start();
//Sender
if (!clientSocket.isClosed())
new Thread(new Sender(clientSocket)).start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Receiver thread code:
class Receiver implements Runnable {
private Socket socket;
Receiver(Socket s) throws IOException {
socket = s;
}
#Override
public void run() {
try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
String received;
do {
received = in.readLine();
if (received == null) break;
System.out.println("Them: " + received);
} while (!received.contains("/dropmic"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
Sender thread code:
class Sender implements Runnable {
private Socket socket;
Sender(Socket s) throws IOException {
socket = s;
}
#Override
public void run() {
try (PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))) {
String sent;
do {
System.out.print("You: ");
sent = stdIn.readLine();
if (sent == null) break;
out.println(sent);
} while (!sent.contains("/dropmic"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server output:
java.net.SocketException: Socket is closed
at java.net.Socket.getOutputStream(Socket.java:943)
at Sender.run(Sender.java:16)
at java.lang.Thread.run(Thread.java:745)
java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:170)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at Receiver.run(Receiver.java:19)
at java.lang.Thread.run(Thread.java:745)
Process finished with exit code 0
Client output (Still running):
Chat connected
You: java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Socket.java:903)
at Receiver.run(Receiver.java:16)
at java.lang.Thread.run(Thread.java:745)
You are using a try-with-resources statement, and putting the socket as the resources. However, when you create the new thread, this try-with-resources reaches the end of its code and closes the sockets. Put your sockets inside the actual try statement and close them manually to fix this.

How to reproduce "java.net.SocketException.Connection reset"?

I am trying to reproduce "java.net.SocketException.Connection reset" exception.
Wanted to know if there is any program available which could help me simulate it. I tried following Server and client programs to see if I could simulate but I am not able to get any exception. I am using java8.
Server Code-
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
public class SimpleServerApp {
public static void main(String[] args) throws InterruptedException {
new Thread(new SimpleServer()).start();
}
static class SimpleServer implements Runnable {
#Override
public void run() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(3333);
serverSocket.setSoTimeout(0);
//serverSocket.
while (true) {
try {
Socket clientSocket = serverSocket.accept();
BufferedReader inputReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
System.out.println("Client said :"+ inputReader.readLine());
} catch (SocketTimeoutException e) {
e.printStackTrace();
}
}
}catch (Exception e) {
e.printStackTrace();
System.out.println(" EXCEPTION " + e.getStackTrace());
}/*catch (IOException e1) {
e1.printStackTrace();
}*/ /*finally {
try {
if (serverSocket != null) {
serverSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}*/
}
}
}
Client Code -
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
public class SimpleClientApp {
public static void main(String[] args) {
new Thread(new SimpleClient()).start();
}
static class SimpleClient implements Runnable {
#Override
public void run() {
Socket socket = null;
try {
socket = new Socket("localhost", 3333);
PrintWriter outWriter = new PrintWriter(socket.getOutputStream(), true);
System.out.println("Wait");
Thread.sleep(20000);
//System.exit(0);
//throw new Exception("Random exception");
//socket.close();
outWriter.println("Hello Mr. Server!");
}catch (SocketException e) {
e.printStackTrace();
}catch (InterruptedException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} /*finally {
try {
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
*/ }
}
}
Scenario 1.
Start the server program locally.
Start the Client program locally.
Close the client program abruptly (Ctrl C) - I just get output on
Server program "Client said :null"
Scenario 2.
Start the Server program Locally.
Start the client program locally.
Client is connected to server, Then while client program is waiting close the server program abruptly. Still no exception.
Can some tell me some way I could produce the connection reset exception, With working sample code.
None of the answers above worked for me reliably both on Mac and Linux.
After a lot of Googling, I ended with this article explaining how to do it. Just to be clear: I was trying to reproduce the connection reset from the client side, i.e. "Connection reset by peer".
I tried bringing up a process which run netcat, and abruptly killing the process - that only worked on Mac.
I tried socket.close from another thread, same thread - nothing worked.
Simply, all those methods didn't cause the client to send RST to the server, which causes the exception (reset by peer).
The following worked:
Setup any server - in my case Netty (their getting started Discard server will do).
Use the following client code:
final Socket socket = new Socket("localhost", port);;
socket.setSoLinger(true, 0);
final OutputStream outputStream = socket.getOutputStream();
for (int i=0; i <= 500; i++) {
outputStream.write('a');
}
outputStream.write('\n');
outputStream.flush();
socket.close();
Thread.sleep(2000);
The soLinger() was the magic trick. According to the Oracle article cited above, when you call socket.close() it sends a RST to the other side, instead of sending FIN and then waiting for the other side to finish reading what ever was sent until the FIN - i.e. force close.
It took me 1 day of work to find this out, so I hope it will save you time on your work.
There are several ways. I won't post one of them as it is too much abused, but the simple ways to produce it are:
Close a socket immediately you acquire it, without reading anything. This works if the sender is sending to you rather than reading from you.
If you know the sender has sent something, close the socket without reading it in any way.
This works for me:
class Server {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(9999);
Socket s = ss.accept();
InputStream i = s.getInputStream();
i.read();
}
}
client connects and disconnects without closing socket
class Client {
public static void main(String[] args) throws Exception {
Socket s = new Socket("localhost", 9999);
}
}
this results in exception on server
Exception in thread "main" java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at net.Server.main(Server.java:13)
Instead of provoking this exception using Java client code, I found it easier to just write a short Python script:
import struct, socket
s = socket.socket(socket.AF_INET6)
s.connect(("::1", 8000))
s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))
s.close() # provokes Connection Reset at host

Java multi-client server doesn't receive message from client?

I managed to setup a server which will accept & manage multiple socket clients.
but now when I try to send a message, the server just doesn't receive anything, yet I do flush the message.
This is the method that's managing the clients:
public void run() {
while(true) {
for (Client c : this.clients) {
try {
if (c.getStream().read() != -1) {
if (c.getInputStream() != null) {
System.out.println("He sent message");
c.sendMessage("hey client");
}
}
} catch (IOException e) {
c.destruct();
this.clients.remove(c); break;
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Client list:
public ArrayList<Client> clients = new ArrayList<Client>(); // client list
And Client object:
public class Client {
private Socket socket;
private int clientId;
private BufferedReader inStream;
private PrintWriter outStream;
private boolean socketAlive = true;
public Client(Socket sock) {
this.socket = sock;
}
public void setup() {
setInputOutputStream();
System.out.println("New connection: " + this.getIpAddress());
this.sendMessage("Successfully connected!");
}
public BufferedReader getStream() {
return this.inStream;
}
public String getInputStream() {
String toReturn = "";
try {
toReturn = this.inStream.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return toReturn;
}
public void destruct() {
try {
this.inStream.close();
this.inStream = null;
this.outStream.close();
this.outStream = null;
System.out.println("Client destruct: " + this.socket.getLocalSocketAddress());
this.socket.close();
this.socket = null;
} catch (IOException e) {
e.printStackTrace();
}
}
public Socket getConnection() {
return this.socket;
}
private void setInputOutputStream() {
try {
inStream = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
outStream = new PrintWriter(this.socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendMessage(String s) {
this.outStream.println(s);
this.outStream.flush();
}
public String getIpAddress() {
return this.socket.getRemoteSocketAddress().toString();
}
}
And the client side (sender) :
public static void main(String[] args) {
try {
System.out.println("Client started");
Socket sock = new Socket("localhost", 43594);
Scanner scanner = new Scanner(System.in);
String input;
PrintWriter out = new PrintWriter(sock.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
while (true) {
input = scanner.nextLine();
if (input != null) {
out.print(input);
out.flush();
}
}
} catch (IOException e) {
System.out.println("Client error");
}
}
Why is my server not receiving anything?
One thing:
If I send message + disconnect, this what the server will log (It looks like it only sends the message upon disconnect or something, well no, it enters the if block only upon it):
Server is successfully running on port 43594
New connection: /127.0.0.1:57102
He sent message
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at Client.getInputStream(Client.java:32)
at ClientHandler.run(ClientHandler.java:21)
Client destruct: 0.0.0.0/0.0.0.0:43594
What did I do wrong? how can I fix that
Server (main class)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
import java.util.ArrayList;
public class Server {
private int port = 43594;
public void listen() {
System.out.println("Trying to listen...");
try {
final ServerSocket server = new ServerSocket(port);
// Create new thread to handle clients I/O
ClientHandler handler = new ClientHandler(server);
// START it
handler.start();
System.out.println("Server is successfully running on port " + port);
while (true) {
// New connection found create a new Client object
Client cl = new Client(server.accept());
cl.setup();
// add it to clietns list in the I/O handler
handler.clients.add(cl);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// start up
System.out.println("Starting up..");
// server instance
final Server server = new Server();
// create a new thread for server
new Thread(new Runnable() {
#Override
public void run() {
// listen for new connections
server.listen();
}
}).start();
}
}
The client is sending data and the servers is reading.
I think the problem is in Client.getInputStream
this.inStream.readLine(), it reads a line of text.
From documentation:
"Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed."
http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html
If you use read instead, maybe it is going to work. Just use a kind of protocol like sending first 1 or 2 bytes with the length of the message. Or you may send a '\n' from the client.
BTW, the reason for the exception in the server when you send and disconnect in the client side may be due to a TCP fact. The client closed the connection and it probably received a TCP ACK from the server. Then TCP in the client sends a RESET segment. Not so sure though. The server was at this.inStream.readLine() and then it received an exception. Didn't you also received "Connection closed by peer"?
I am not sure why, but I needed to use out.println(input) out.flush() instead of .print() or .write()
I don't have an explanation of why do I need to do that. but it worked.
I think the problem comes from the fact that you've got a list of clients and are trying to manage them with that. I looked up java.net.SocketException: Connection reset, and found this question: What's causing my java.net.SocketException: Connection reset?
The answer to this question comes up with this:
In your case it seems that the connection has been closed by the
server end of the connection. This could be an issue with the request
you are sending or an issue at their end.
This made me think that you aren't holding the connection to the client every time. You store it, and then you lose it, so the message isn't sent. To handle more clients, you might rather want to have a list of IPs, rather than clients, and then you connect when you want to send a message. You can't store the Socket connection. It has to be active. Java (The JVM) has it's own "Garbage Collection" system that'll just kill it.

How to determine that the current client socket has closed and connect to another server?

I want to implement a handler in my code to allow a client to automatically connect to a second instance of a server on the same network if the server connected to this client is not responding after 10 seconds. What am I doing wrong??
private static void connectToServer(String serverHostname, int port) throws UnknownHostException, IOException
{
try {
echoSocket = new Socket(serverHostname, 10118);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(echoSocket
.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Unknown host: " + serverHostname);
System.exit(1);
} catch (IOException e) {
System.err.println("Not connected to server: "
+ serverHostname);
System.exit(1);
}
}
public static void main(String[] args) throws IOException {
listServer.add("10.196.113.31");
listServer.add("10.196.113.27");
BufferedReader stdIn = new BufferedReader(new InputStreamReader(
System.in));
try {
if (args.length > 0)
serverHostname = args[0];
System.out.println("Trying to connect to host " + serverHostname
+ " at port 10118.");
connectToServer(getServer(), 10118);
echoSocket.setSoTimeout(10000);
String userInput;
System.out.print("Input: ");
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
if (!echoSocket.isConnected()) connectToServer(serverHostname, 10118);
System.out.println("echo: " + in.readLine());
System.out.print("Input: ");
}
} catch (SocketTimeoutException e) {
NextServer();
connectToServer(getServer(), 10118);
System.out.println("Timeout");
// TODO: handle exception
}
out.close();
in.close();
stdIn.close();
echoSocket.close();
}
private static void NextServer(){
idServer ++;
}
private static String getServer(){
return listServer.get(idServer);
}
EDIT
When I run the server, then the client, everything is fine. Then I start the second server on another machine on the same network, and try to send text from the same client, the client should automatically detect that the first server is disconnected, connect to the second instance of the server and send the text message. Here is the exception i am getting:
Exception in thread "main" java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source) at
sun.nio.cs.StreamDecoder.readBytes(Unknown Source) at
sun.nio.cs.StreamDecoder.implRead(Unknown Source) at
sun.nio.cs.StreamDecoder.read(Unknown Source) at
java.io.InputStreamReader.read(Unknown Source) at
java.io.BufferedReader.fill(Unknown Source) at
java.io.BufferedReader.readLine(Unknown Source) at
java.io.BufferedReader.readLine(Unknown Source) at
Q3.Client.main(Client.java:62)
If you want your client to do something when the server disconnects the connection, you need to do more than just catch SocketTimeoutException. As the stacktrace shows, a dropped connection will result in a generic SocketException being thrown. You should catch this also.
In other words, it looks like you are only handling the case where the initial connection to the server from the client fails; and you are not handling the case where an existing condition is dropped.
If the server is not responding to connect, your setSoTimeout will not cover that case, so make sure you have a timeout in the connection establishment code. Write this:
SocketAddress a = new InetSocketAddress(serverHostname, 10118);
echoSocket = new Socket();
echoSocket.connect(a, 10000);

Categories

Resources