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.
Related
I have a problem with my application. If I run server and clients on the same computer it works fine. No errors. But if I run server on one PC and I try to connect form other computers I get "timeout exception" or If I manage to connect I will get errors while sending data.
Server code (not all):
// server loop - listening for connections
public void runServer()
{
try {
ServerSocket serverSocket = new ServerSocket(port, 10);
System.out.println("Server up.");
while (true)
{
System.out.println("waiting for new connection...");
Socket socket = serverSocket.accept();
System.out.println("Someone connected");
Thread t = new Thread (new ServerThread(socket));
t.start();
System.out.println("new thread");
}
} catch (IOException ex) {
Logger.getLogger(KsiegarniaServer.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Server error");
}
// this is thread that is opened when new client connects
private class ServerThread implements Runnable
{
Socket socket;
ObjectInputStream in;
ObjectOutputStream out;
String playerLogin;
int playerID;
public ServerThread(Socket s) {
this.socket = s;
}
public void run() {
try {
Msg m;
in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());
System.out.println("Streams are ready!");
while ( (m = (Msg) in.readObject()).getHeader() != 0 )
{
respondToClient(m); // switch with cases that are running depending on message header
}
} catch (IOException ex) {
//Logger.getLogger(SpaceBattleGameServer.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("IOException - public void run()");
} catch (ClassNotFoundException e) {
System.out.println("ClassNotFoundException - public void run()");
} finally {
// other stuff
}
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);
}
}
}
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?
It's hard to fit it in the title but every time a client disconnects, a lot of exceptions are thrown and the server does not allow any more connections after the DC. Here is the error i get:
java.net.SocketException: Socket closed
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.ObjectInputStream$PeekInputStream.read(Unknown Source)
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)
at ClientHandler.setupStreams(ClientHandler.java:34)
at ClientHandler.run(ClientHandler.java:22)
Now i expect to get this exception because yea... The client closed the connection between the server and the client. but what i can't understand is why the client wont allow connections after the first disconnect. I am assuming that it breaks out of the while loop but why? Here is the code that takes the clients connection, accepts it and hands it off to the handler class:
public class ClientConnector
{
public static JTextField userText;
public static JTextArea chatWindow;
public static int Connections = 0;
public static Vector sendQueue = new Vector();
public static ArrayList<ObjectOutputStream> Streams = new ArrayList<ObjectOutputStream>();
public static Scanner input = new Scanner(System.in);
public ClientConnector()
{
}
public static void runServer()
{
try
{
System.out.println("[Info] Attempting to bind to port 1337.");
#SuppressWarnings("resource")
ServerSocket serversocket = new ServerSocket(1337);
System.out.println("[Info] Bound to port 1337.");
System.out.println("[Info] Waiting for client connections...");
while(true)
{
Socket socket = serversocket.accept();
new ClientHandler(socket).start();
Connections += 1;
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
That's fairly simple. Now for the code that handles the clients connection:
public class ClientHandler extends Thread
{
Socket ConnectedClient;
static ObjectOutputStream Output;
static ObjectInputStream Input;
public static boolean isError = false;
public static int updateCounter = 0;
ClientHandler(Socket socket)
{
ConnectedClient = socket;
}
public void run()
{
while(true)
{
setupStreams();//22
WhileChatting();
}
}
public void setupStreams()
{
try
{
if(isError == false)
{
Output = new ObjectOutputStream(ConnectedClient.getOutputStream());
Input = new ObjectInputStream(ConnectedClient.getInputStream());//34
ClientConnector.Streams.add(Output);
}
}
catch (IOException e)
{
isError = true;
e.printStackTrace();
}
}
public static void WhileChatting()
{
String Message = "";
do
{
try
{
if(isError == false)
{
Message = (String)Input.readObject();
for(int i = 0; i < ClientConnector.Streams.size(); i++)
{
ClientConnector.Streams.get(i).writeObject(Message);
System.out.println(Message);
}
}
}
catch(ClassNotFoundException CNFE)
{
isError = true;
CNFE.printStackTrace();
}
catch(EOFException eof)
{
for(int i = 0; i < ClientConnector.Streams.size(); i++)
{
try
{
Output.close();
Input.close();
ClientConnector.Streams.get(i).close();
ClientConnector.Streams.remove(i);
System.out.println("Connection lost");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
catch (IOException e)
{
isError = true;
e.printStackTrace();
}
}
while(Message != "/disconnect");
}
public static void sendMessage(String message)
{
try
{
if(isError == false)
{
Output.writeObject(message);
System.out.println(message);
}
}
catch(IOException Ex)
{
isError = true;
Ex.printStackTrace();
}
}
public static void sendServerMessage(String message)
{
int Limit = 0;
try
{
for(int i = 0; i < ClientConnector.Streams.size(); i++)
{
if(Limit == 0)
{
ClientConnector.Streams.get(i).writeObject("\247c[Server] \247d" + message);
System.out.println("\247c[Server] \247d" + message);
Limit = 1;
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void closeConnections()
{
try
{
if(isError == false)
{
Output.close();
Input.close();
//ConnectedClient.close();
}
}
catch(IOException Ex)
{
isError = true;
Ex.printStackTrace();
}
}
}
I have commented in the affected lines.
The error happens after the client disconnects. I don't know if it's the exception causing the while loop to break or weather it's something else. How can i make this code continute to allow incoming connectinos after the client disconnects. I have tried debugging and using System.out.println. Thanks in advance to all who answered.
Now i expect to get this exception because yea... The client closed the connection between the server and the client.
No. This exception means that you closed the Socket and then tried to do further I/O on it. Nothing to do with the peer.
but what i can't understand is why the client wont allow connections after the first disconnect.
There are numerous problems with your code.
You must use the same ObjectInputStream and ObjectOutputStream for the life of the Socket, at both ends. At present you are creating a new pair, and adding them to the data structure, every time around the loop.
When you catch EOFException on one Socket, you are closing all the sockets. You should only close one, the one you got the exception from, and then you must break out of all loops and allow the thread to exit.
You should basically change your while loop from while (true) to while (!isError) and stop testing isError everywhere else. I would get rid of the whileChatting method and incorporate it into this while loop. And you don't need the inner do loop. You only need one loop that reads until EOS or a disconnect command.
I have the follwing code which is a thread pool in java which accepts only one client
public class ServerThread implements Runnable {
ServerSocket serverSocket;
Socket clientSocket;
protected boolean isStopped = false;
int serverPort = 6500;
private String serverIpAddress = "127.0.0.1";
DataInputStream is;
ObjectOutputStream os=null;
protected BlockingQueue queue = null;
protected ExecutorService threadPool2 =
Executors.newFixedThreadPool(1);
public ServerThread(BlockingQueue queue) {
this.queue=queue;
}
public void run() {
try {
InetSocketAddress serverAddr = new InetSocketAddress(serverIpAddress, serverPort);
serverSocket = new ServerSocket();
serverSocket.bind(serverAddr);
System.out.println("s-a creat");
} catch (UnknownHostException e) {
System.err.println("Don't know about host");
} catch (IOException e) {
e.printStackTrace();
}
while(!isStopped()){
clientSocket=null;
try{
clientSocket = serverSocket.accept();
}
catch(Exception e)
{
e.printStackTrace();
}
WorkerServerRunnable workerRunnable = new WorkerServerRunnable(queue,clientSocket);
this.threadPool2.execute(workerRunnable);
}
this.threadPool2.shutdown();
System.out.println("Server Stopped.");
}
private synchronized boolean isStopped(){
return this.isStopped;
}
public synchronized void stop() {
this.isStopped = true;
try {
this.serverSocket.close();
} catch (IOException e) {
throw new RuntimeException("Error closing server", e);
}
}
}
But the problem is that I cannot get my server in ON state.
I mean once I press run I get the following error:
java.net.SocketException: Socket is not bound yet
at java.net.ServerSocket.accept(Unknown Source)
at servers.ServerThread.run(ServerThread.java:60)
at java.lang.Thread.run(Unknown Source)
java.net.BindException: Address already in use: JVM_Bind
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at servers.ServerThread.run(ServerThread.java:44)
at java.lang.Thread.run(Unknown Source)
Even if I shutdown my whole app and run it again still the same error....has anyone any idea why?Thank u!
Some other program is already using port 6500. Check that you're not running another instance of your program.
Try running
netstat -lp
to see what processes are using which ports. Make sure the port on which you wish to listen is not listed in the output from netstat.
In the run() method, when you are creating a ServerSocket and assigning it to serverSocket variable:
serverSocket = new ServerSocket();
Please give a port number in the ServerSocket constructor, like 5000
serverSocket = new ServerSocket(5000);