I'm currently working on a small chat-program. The 2 classes I have a problem with are the classes containing the clientside and the serverside of a socket. I want the client to read the lines the server sends. I get this error:
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 MainPanel.run(MainPanel.java:121)
at java.lang.Thread.run(Unknown Source)
I read, that this happens, because the socket connection gets closed on the serverside, but I can't see, where that happens in the code. Can someone explain, why this happens or how to fix it?
Codesnippet from client:
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true) {
chatArea.append(br.readLine() + "\n"); //line 121
}
} catch(Exception ex) { ex.printStackTrace(); }
Codesnippet from server:
while(true) {
System.out.println("Waiting for someone to connect.");
Socket currentSocket = serverSocket.accept();
System.out.println("Someone connected.");
sockets.add(currentSocket);
new Thread(new Runnable() {
public void run() {
try {
while(true) {
BufferedReader br = new BufferedReader(new InputStreamReader(currentSocket.getInputStream()));
String input = br.readLine();
for(Socket socket : sockets) {
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
pw.println(input);
}
}
} catch(Exception ex) {
sockets.remove(currentSocket);
System.out.println("One connection lost.");
}
}
}).start();
}
When server application gets terminated, the TCP session which is bound to Socket object on the client side throws SocketException which is purely normal. There is nothing wrong with your scenario. What you have to do is that you have to handle SocketException both on the clientside and the server server side. Either client or server may terminate the TCP session. On the client side you may have a logic that may try to reinitialize the TCP session, whereas on the server side, you clear objects related to the TCP session.
a sample runner class :
public class TCPProcessor implements Runnable {
private Socket s;
private Thread th;
public TCPProcessor(Socket s) {
this.s = s;
th = new Thread(this);
tcpProcessors.add(this);
th.start();
}
public void stop() {
try {
s.close();
} catch (Exception e) {
LOGGER.trace("socket couldn't be closed");
}
th.interrupt();
}
#Override
public void run() {
Request r = null;
try {
ObjectInputStream inFromClient = new ObjectInputStream(s.getInputStream());
ObjectOutputStream outToClient = new ObjectOutputStream(s.getOutputStream());
while (isStarted()) {
final Object receivedObject = inFromClient.readObject();
// LOGGER.debug("Receiving "
// + ((Request) receivedObject).getRequestType() + " "
// + receivedObject);
r = (Request) receivedObject;
processId.set(r.getProcessId());
Response rs = new Response();
rs.setRequest(r);
rs.setServerFrom(GoldenNodeServer.this);
if (getOperationBase() != null) {
try {
Object s = ReflectionUtils.callMethod(getOperationBase(), r.getMethod(), r.getParams());
rs.setReturnValue(s);
} catch (Exception e) {
rs.setReturnValue(e);
}
outToClient.writeObject(rs);
} else {
rs.setReturnValue(new NoClientProxySetException());
}
}
} catch (EOFException e) {
// LOGGER.trace("eof occured");
} catch (SocketException e) {
if (e.toString().contains("Socket closed") || e.toString().contains("Connection reset")
|| e.toString().contains("Broken pipe")) {
} else {
stop();
LOGGER.error("Error occured" + (r == null ? "" : " while processing " + r) + " ", e.toString());
}
} catch (IOException | ClassNotFoundException e) {
stop();
LOGGER.error("Error occured" + (r == null ? "" : " while processing " + r) + " ", e.toString());
} finally {
tcpProcessors.remove(this);
}
}
}
Related
public class NewClass {
ServerSocket myServerSocket;
boolean ServerOn = true;
public NewClass() {
try {
myServerSocket = new ServerSocket(8888);
} catch (IOException ioe) {
System.out.println("Could not create server socket on port 8888. Quitting.");
System.exit(-1);
}
while (ServerOn) {
try {
Socket clientSocket = myServerSocket.accept();
ClientServiceThread cliThread = new ClientServiceThread(clientSocket);
cliThread.start();
} catch (IOException ioe) {
System.out.println("Exception found on accept. Ignoring. Stack Trace :");
ioe.printStackTrace();
}
}
try {
myServerSocket.close();
System.out.println("Server Stopped");
} catch (Exception ioe) {
System.out.println("Error Found stopping server socket");
System.exit(-1);
}
}
public static void main(String[] args) {
new NewClass();
}
class ClientServiceThread extends Thread {
Socket myClientSocket;
boolean m_bRunThread = true;
public ClientServiceThread() {
super();
}
ClientServiceThread(Socket s) {
myClientSocket = s;
}
public void run() {
BufferedReader in = null;
PrintWriter out = null;
System.out.println(
"Accepted Client Address - " + myClientSocket.getInetAddress().getHostName());
try {
in = new BufferedReader(new InputStreamReader(myClientSocket.getInputStream()));
out = new PrintWriter(new OutputStreamWriter(myClientSocket.getOutputStream()));
while (m_bRunThread) {
String clientCommand = in.readLine();
if (clientCommand != null) {
System.out.println("Client Says :" + clientCommand);
}
if (!ServerOn) {
System.out.print("Server has already stopped");
out.println("Server has already stopped");
out.flush();
m_bRunThread = false;
}
if (clientCommand.equalsIgnoreCase("quit")) {
m_bRunThread = false;
System.out.print("Stopping client thread for client : ");
} else if (clientCommand.equalsIgnoreCase("end")) {
m_bRunThread = false;
System.out.print("Stopping client thread for client : ");
ServerOn = false;
} else {
out.println("Server Says : " + clientCommand);
out.flush();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
in.close();
out.close();
myClientSocket.close();
System.out.println("...Stopped");
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
}
Client Code
public class Client {
public static void main(String[] args) throws IOException {
Socket s = new Socket(InetAddress.getLocalHost(), 8888);
PrintWriter out =new PrintWriter(s.getOutputStream(), true);
out.print("KKKKKKKKKKKKK \r\n");
out.flush();
out.close();
}
The purpose of the above code is to create server socket and client socket to pass data between server and client.When the client sends the data to server .server grab the message and print it on the screen but with following exception.The pop up from the String clientCommand = in.readLine(); line which appeared on server code.
java.net.SocketException: Connection reset
Your code is invalid. Your server code relies on the client implementing the protocol correctly, which this client doesn't. Bad habit. Defensive coding is required. If clientCommand == null you must exit this read loop and close the socket. Your present code will attempt to write to the closed connection, which produces exactly this exception ... later.
I had written a small code where I am trying to listen on particular port as follows (just trying out something) :
public class Test {
public static class MyThread extends Thread {
ServerSocket ss = null;
public MyThread(int port){
try {
ss = new ServerSocket(port);
} catch (IOException e) {
System.out.println("Exception in assigning port : " + port);
e.printStackTrace();
}
}
public void stopListening(){
try {
ss.close();
} catch (IOException e) {
System.out.println("Exception in closing socket : " + ss.getLocalPort());
e.printStackTrace();
}
}
public void run(){
try {
ss.accept();
} catch (IOException e) {
System.out.println("Exception in listening on port : " + ss.getLocalPort());
e.printStackTrace();
}
}
}
public static void main(String[] args) {
List<MyThread> threadList = new LinkedList<>();
for (int i = 50000; i < 50005; i++) {
MyThread thread = new MyThread(i);
threadList.add(thread);
thread.start();
}
try {
Thread.sleep(5000);
} catch (InterruptedException e2) {
e2.printStackTrace();
}
for (MyThread myThread : threadList) {
myThread.stopListening();
}
}
}
But I am unable to start even a single thread , for every ss.accept() I keep getting :
Exception in listening on port :
I get the following exception in each case :
java.net.SocketException: socket closed
at java.net.DualStackPlainSocketImpl.accept0(Native Method)
at java.net.DualStackPlainSocketImpl.socketAccept(Unknown Source)
at java.net.AbstractPlainSocketImpl.accept(Unknown Source)
at java.net.PlainSocketImpl.accept(Unknown Source)
at java.net.ServerSocket.implAccept(Unknown Source)
at java.net.ServerSocket.accept(Unknown Source)
at com.harman.hlacssmdw.Test$MyThread.run(Test.java:40)
I checked the ports from 50000 to 50000 using netstat -anp , none of theme are occupied.
I am unable to understand what am I doing wrong, Please help !!!
The ServerSocket is closed because you close it by calling stopListening(). That leads to an Exception for all Threads waiting on accept() of that ServerSocket.
I have created client server application in the client side when i send multiple requests to the server some time later it gives below error.When i monitor TCPview there are lot of port connections on CLOSE_WAIT status.Has any one come across with such issue.Please find the bellow error log
java.net.SocketException: No buffer space available (maximum connections reached?): connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:529)
at java.net.Socket.connect(Socket.java:478)
at java.net.Socket.<init>(Socket.java:375)
at java.net.Socket.<init>(Socket.java:189)
at com.lk.cc.socketserver.Main.isHostRunning(Main.java:90)
at com.lk.cc.socketserver.Main.main(Main.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Exception in thread "main" java.lang.NullPointerException
at com.lk.cc.socketserver.Main.isHostRunning(Main.java:102)
at com.lk.cc.socketserver.Main.main(Main.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Server Host class
public class ServerHost extends Thread {
private ServerSocket serverSocket;
public ServerHost(int port) throws IOException {
serverSocket = new ServerSocket(port);
}
public void run() throws IOException{
while (true) {
Socket server = null;
DataInputStream in = null;
DataOutputStream out = null;
try {
System.out.println("Host 1 Established .. ");
System.out.println("Waiting for client on port " +
serverSocket.getLocalPort() + "...");
server = serverSocket.accept();
System.out.println("Just connected to "
+ server.getRemoteSocketAddress());
in =
new DataInputStream(server.getInputStream());
if (in.available() > 0) {
System.out.println("Recieved client message :" + in.readUTF());
out = new DataOutputStream(server.getOutputStream());
// send recieved response from host X to client
out.writeUTF("Response from Host 1 " + server.getLocalSocketAddress() + " \nGoodbye!");
System.out.println("client socket isClosed() " + server.isClosed());
}
} catch (SocketTimeoutException s) {
System.out.println("Socket timed out!");
// break;
} catch (IOException e) {
e.printStackTrace();
// break;
} finally {
if (out != null) {
try {
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (server != null) {
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
int port = 7881;
try {
Thread t = new ServerHost(port);
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client
public class Main {
private static ArrayList<HostConnections> hostList;
public static void init() {
hostList = new ArrayList<HostConnections>();
hostList.add(new HostConnections("localhost", 7881));
hostList.add(new HostConnections("localhost", 7882));
hostList.add(new HostConnections("localhost", 7883));
hostList.add(new HostConnections("localhost", 7884));
}
public static void main(String[] args) {
// write your code here
boolean hostStatus=true;
init();
while (hostStatus) {
System.out.println("Used " + hostList.get(0));
HostConnections nextHost = hostList.get(0);
//Collections.rotate(hostList, -1);
System.out.println(hostList);
hostStatus = isHostRunning(nextHost);
System.out.println(hostStatus);
}
}
private static boolean isHostRunning(HostConnections availableHost) {
boolean isAlive = false;
Socket client=null;
try {
client = new Socket(availableHost.getHostIpAddress(), availableHost.getHostPort());
//client.getInputStream().close();
// client.getOutputStream().close();
isAlive = true;
} catch ( Exception e) {
e.printStackTrace();
}finally {
try {
//client.getOutputStream().flush();
client.close();
client.isClosed();
System.out.println(client.isClosed());
} catch (IOException e) {
e.printStackTrace();
}
}
return isAlive;
}
}
My requirement is to check all the connections in the list are available everytime.
Thanks
You're leaking sockets somewhere. CLOSE_WAIT means that TCP has received a close from the peer and is waiting for the local application to close the socket.
You should also try a sleep in that testing loop. You're burnng sockets like there is no tomorrow.
In fact I question the entire purpose. The only reliable way to know whether any resource is available is to try to use it and handle the errors as they arise in the normal course of execution. Anything else is tantamount to fortune-telling.
NB:
flush() before close() is redundant.
Calling isClosed() and available() is usually a waste of time, and this is no exception.
Are you aware that this code only tests one host?
I'm rather new to server sockets, trying to learn how to code a socket (ive had past experience with using sockets like winsock but this is my first time actually coding one in java).
This is the error I keep getting:
Couldn't get I/O for the connection to: 0
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
This is the code:
public static void main(String args[]) {
ServerSocket MyService = null;
Socket clientSocket = null;
Integer clientNum = 0;
Integer inputID, outputID;
try {
MyService = new ServerSocket(hidden);
} catch (IOException e) {
e.printStackTrace();
}
try {
clientSocket = MyService.accept();
ObjectInputStream input = new ObjectInputStream(clientSocket.getInputStream());
ObjectOutputStream output = new ObjectOutputStream(clientSocket.getOutputStream());
Float inputFloat = null;
Float outputFloat = null;
Protocol protocol = new Protocol();
outputFloat = protocol.processFloatInput(null);
while(true) {
if(input.readObject().getClass().equals(inputFloat.getClass())) {
System.out.println("true");
if ((inputFloat = input.readFloat()) != null) {
outputFloat = protocol.processFloatInput(inputFloat);
output.writeObject(outputFloat);
System.out.println("Float value = " + inputFloat);
}
input.close();
output.flush();
output.close();
}
if(input.readObject().getClass().equals(Integer.TYPE)) {
if ((inputID = input.readInt()) != null) {
outputID = protocol.processIntegerInput(inputID);
output.writeObject(inputID);
System.out.println("Client " + outputID + " connected.");
}
input.close();
output.flush();
output.close();
}
}
} catch (UnknownHostException e) {
System.err.println("Don't know about host: hostname");
} catch (IOException e) {
//Error printed
System.err.println("Couldn't get I/O for the connection to: " + clientNum);
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
};
In past tests, i was able to connect to the server, but since I want to check the input data type before operating, I get this.
Thanks for the help :)
EOFException just means you got to the end of the stream. It's normal.
Your problem is that you're reading twice for every object written: once to get its class and again to get the object. You don't get the same object again, you get the next object, so you run out eventually.
You need to store the result of readObject() in a variable, then test its class, then cast it appropriately.
I am getting a lot of connection reset errors, trough debugging i found out that the code is found within these lines:
//set up output stream for objects
output = new ObjectOutputStream(socket.getOutputStream());
output.flush(); //flush the output buffer to send header information
// Read a message sent by client application
ois = new ObjectInputStream(socket.getInputStream());
String message = (String) ois.readObject();
The error occurs at this line:
String message = (String) ois.readObject();
The error message:
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 java.io.ObjectInputStream$PeekInputStream.peek(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.peek(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at org.bitbucket.c4d3r.ConnectionListener.listen(ConnectionListener.java:47)
at org.bitbucket.c4d3r.ConnectionListener.<init>(ConnectionListener.java:27)
at org.bitbucket.c4d3r.ConnectionHandler.connectionServer(ConnectionHandler.java:46)
at org.bitbucket.c4d3r.ConnectionHandler.run(ConnectionHandler.java:24)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
I know that the connection reset is caused by a socket that's closed unexpectedly, however i am quite new to sockets and i am unable to find what i am doing wrong. Therefore i was hoping that someone could help me out with this. For a better vision of everything i have copied a bigger block of code beneath
private DomainController dc;
private Socket socket;
private boolean changed;
private ObjectOutputStream output;
private ObjectInputStream ois;
private Map json;
public ConnectionListener(DomainController dc, Socket socket) {
this.dc = dc;
this.socket = socket;
listen();
}
#Override
public void run() {
listen();
return;
}
#SuppressWarnings("finally")
public void listen() {
try
{
//set up output stream for objects
output = new ObjectOutputStream(socket.getOutputStream());
output.flush(); //flush the output buffer to send header information
// Read a message sent by client application
ois = new ObjectInputStream(socket.getInputStream());
String message = (String) ois.readObject();
boolean inProgress;
//CHECK IF THERE ARE GIVEN COMMANDS
if(message.substring(0, 8).equalsIgnoreCase("COMMAND="))
{
switch(message.substring(8))
{
case "askMinigames":
//System.out.println("Sending minigames list");
output.writeObject(new String(dc.getProp().getProperty("minigames")));
output.flush(); //flush output to client
break;
}
}
} catch (SocketException ex) {
System.out.printf("Connection reset\n");
ex.printStackTrace();
} catch (IOException e) {
System.out.println("Input exception");
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
try
{
if(ois != null) {
ois.close();
}
if(output != null) {
output.close();
}
if(socket != null) {
socket.close();
}
}
catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
}
You need to use the same object input and output streams for the life of the socket, at both ends. As you are just sending strings, I don't really see why you're using object streams at all: you could use e.g. DataOutputStream.writeUTF() and DataInputStream.readUTF().