Closing Server Socket - java

I'm trying to close a server but i receive:
java.net.SocketException: Socket closed
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398)
at java.net.ServerSocket.implAccept(ServerSocket.java:530)
at java.net.ServerSocket.accept(ServerSocket.java:498)
at THREAD.MioServer.AvviaServer(MioServer.java:21)
at THREAD.Avviamento.run(Avviamento.java:16)
at java.lang.Thread.run(Thread.java:745)
This is my code:
package THREAD;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.*;
import java.util.Scanner;
public class MioServer {
public int port;
public MioServer(int port) {
super();
this.port = port;
}
ServerSocket serverSocket=null;
Socket socket=null;
public void AvviaServer() throws IOException {
serverSocket=new ServerSocket(port);
System.out.println("serverSocket partito "+ port);
socket=serverSocket.accept();
System.out.println("socket partita");
Scanner in=new Scanner(socket.getInputStream());
PrintWriter out=new PrintWriter(socket.getOutputStream());
while (true) {
String line=in.nextLine();
if (line=="quit") {
break;
}
}
}
public void ferma() throws IOException {
if (socket==null); {
socket=new Socket();
socket.close();
System.out.println("cretino");
serverSocket.close();
}
if (socket!=null) {
socket.close();
socket=null;
serverSocket.close();
System.out.println("chiuso server(?)");
serverSocket=null;
}
}
}
and
package THREAD;
import java.io.IOException;
public class Avviamento implements Runnable{
public MioServer server;
public Avviamento(MioServer server) {
super();
this.server = server;
}
#Override
public void run() {
try {
server.AvviaServer();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package THREAD;
import java.io.IOException;
public class Fermamento implements Runnable{
public MioServer server;
public Fermamento(MioServer server) {
super();
this.server = server;
}
#Override
public void run() {
try {
server.ferma();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
LISTENER:
package LISTENERS;
import java.awt.event.*;
import java.io.IOException;
import javax.swing.*;
import THREAD.*;
public class MioListener implements ActionListener {
public int port=3000;
public MioServer server=new MioServer(3000);
#Override
public void actionPerformed(ActionEvent e) {
JButton b=(JButton) e.getSource();
Avviamento avvio=new Avviamento(server);
Thread avviamento=new Thread(avvio);
Fermamento ferma=new Fermamento(server);
Thread fermamento=new Thread(ferma);
if (b.getText().equals("Avvia")) {
System.out.println("Tasto avvia premuto");
avviamento.start();
}
if (b.getText().equals("Stop")) {
System.out.println("Tasto stop premuto");
fermamento.start();
}
}
Thanks for the help.

I'm trying to close a server but i receive:
java.net.SocketException: Socket closed
It's no wonder that your server thread throws up an exception when the Fermamento thread's server.ferma() closes the serverSocket, quasi pulling the rug from under the server's feet.
You could simply catch the exception with something like:
try { socket=serverSocket.accept(); } catch (SocketException e) { return; }

Related

Why socket closing itself after sending data once?

I have a client-server app.
It opens a socket on client side, then I input data to send, it's also sent to other clients, but then the socket is closed. Why? I have tried many different approaches, like shifting din and dout to thread itself, adding some handlers, etc. But no progress yet.
I saw some other problems like this, but the solutions there are not applicable to my problem (I am not so experienced in sockets). Would like a solution to my specific problem.
Errors:
java.net.SocketException: Socket is closed
at java.base/java.net.Socket.getInputStream(Socket.java:927)
at com.uniqueapps.network.ClientThread.lambda$run$1(ClientThread.java:23)
at java.base/java.lang.Thread.run(Thread.java:833)
java.net.SocketException: Socket is closed
at java.base/java.net.Socket.getOutputStream(Socket.java:998)
at com.uniqueapps.network.ClientThread.lambda$run$0(ClientThread.java:28)
at java.base/java.lang.Thread.run(Thread.java:833)
Exception in thread "Thread-2" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
at com.uniqueapps.network.ClientThread.lambda$run$0(ClientThread.java:27)
at java.base/java.lang.Thread.run(Thread.java:833)
Server.java codes:
package com.uniqueapps.network;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
public class Server {
final static int PORT = 5555;
static ServerSocket serverSocket;
static ArrayList<ClientThread> clients = new ArrayList<>();
public static void main(String[] args) {
try {
serverSocket = new ServerSocket(PORT);
new Thread(() -> {
while (true) {
try {
Socket clientSocket = serverSocket.accept();
ClientThread client = new ClientThread(clientSocket);
client.run();
clients.add(client);
System.out.println("New client joined: " + client.socket.getLocalPort());
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ClientThread.java codes:
package com.uniqueapps.network;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
public class ClientThread implements Runnable {
Socket socket;
public ClientThread(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
new Thread(() -> {
boolean run = true;
while (run) {
try (DataInputStream din = new DataInputStream(socket.getInputStream())) {
String text = din.readUTF();
if (!text.equals("")) {
new Thread(() -> {
for (ClientThread clientThread : Server.clients) {
try (DataOutputStream dout = new DataOutputStream(clientThread.socket.getOutputStream())) {
dout.writeUTF(text);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
} catch (EOFException ignored) {
} catch (SocketException e) {
e.printStackTrace();
Server.clients.remove(this);
run = false;
System.out.println("Client left: " + socket.getLocalPort());
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
Client.java codes:
package com.uniqueapps.network;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost", 5555);
socket.setKeepAlive(true);
new Thread(() -> {
try {
DataOutputStream dout = new DataOutputStream(socket.getOutputStream());
Scanner scn = new Scanner(System.in);
while (true) {
String text = scn.nextLine();
if (!text.equals("")) {
try {
dout.writeUTF(text);
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
DataInputStream din = new DataInputStream(socket.getInputStream());
while (true) {
try {
String text = din.readUTF();
if (!text.equals("")) {
System.out.println(text);
}
} catch (EOFException ignored) {
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Edit:
Thanks to Michael Lee, i understood the problem i have been trying to understand for weeks. I remade the code, but i am stuck a place.
I got to know that the .run(); method of "runnable" halts the current thread, but .start(); of "thread" doesn't. So i removed threads from all places, except one. This place is still getting the "Socket closed" error (If i keep runnable here, then the thread is halted, and the message not relayed to other clients). How can i overcome this?
Server.java:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
public class Server {
final static int PORT = 8686;
static ServerSocket serverSocket;
static ArrayList<ClientThread> clients = new ArrayList<>();
public static void main(String[] args) {
try {
serverSocket = new ServerSocket(PORT);
System.out.println("Server ready! Running on port " + PORT);
while (true) {
try {
Socket clientSocket = serverSocket.accept();
System.out.println("New client joined: " + clientSocket.getPort());
ClientThread client = new ClientThread(clientSocket);
System.out.println("Created thread for client.");
clients.add(client);
System.out.println("Added client to list.");
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ClientThread.java:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
public class ClientThread extends Thread {
Socket socket;
public ClientThread(Socket socket) {
this.socket = socket;
this.start();
System.out.println("Started thread for client.");
}
#Override
public void run() {
try {
boolean run = true;
DataInputStream din = new DataInputStream(socket.getInputStream());
while (run) {
try {
String text = din.readUTF();
if (!text.equals("")) {
for (ClientThread clientThread : Server.clients) {
try (DataOutputStream dout = new DataOutputStream(clientThread.socket.getOutputStream())) {
dout.writeUTF(text);
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (EOFException ignored) {
} catch (SocketException e) {
e.printStackTrace();
Server.clients.remove(this);
run = false;
System.out.println("Client left: " + socket.getPort());
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client.java:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
public class ClientThread extends Thread {
Socket socket;
public ClientThread(Socket socket) {
this.socket = socket;
this.start();
System.out.println("Started thread for client.");
}
#Override
public void run() {
try {
boolean run = true;
DataInputStream din = new DataInputStream(socket.getInputStream());
while (run) {
try {
String text = din.readUTF();
if (!text.equals("")) {
for (ClientThread clientThread : Server.clients) {
try (DataOutputStream dout = new DataOutputStream(clientThread.socket.getOutputStream())) {
dout.writeUTF(text);
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (EOFException ignored) {
} catch (SocketException e) {
e.printStackTrace();
Server.clients.remove(this);
run = false;
System.out.println("Client left: " + socket.getPort());
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
In your ClientThread, after din.readUTF(); if (!text.equals("")) { ..., you should directly start processing the incoming data in current thread, rather than initializing a new thread to handle them.
Because in you current thread, the one holding the connected socket, probably closed before the new thread has not even started up. As Java Docs says:
void close() throws Exception
Closes this resource, relinquishing any underlying resources. This method is invoked automatically on objects managed by the try-with-resources statement.
That is why you got Socket Closed exceptions.
One more thing is that, there are too many threads in either Server or Client. Most of time such things are unnecessary, say, for a rather simple application. Because they are not quite managed well in your codes, which more likely makes your program behave unexpectedly in the future. Try use threads only if necessary, instead of using them as much as possible.

Java client-server chat application getting java.net.SocketException: Socket closed

I am Trying to create a simple client-server application for global chat I am getting the following error when quitting the connection from client Side.
java.net.SocketException: Socket closed
at java.net.SocketInputStream.read(SocketInputStream.java:203)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.net.SocketInputStream.read(SocketInputStream.java:223)
at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:337)
at java.io.DataInputStream.readUTF(DataInputStream.java:589)
at java.io.DataInputStream.readUTF(DataInputStream.java:564)
at ReadFromServer.run(ChatClient.java:25)
and when client crashes without using Quit this error
java.io.EOFException
at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:340)
at java.io.DataInputStream.readUTF(DataInputStream.java:589)
at java.io.DataInputStream.readUTF(DataInputStream.java:564)
at Clients.run(ChatServer.java:34)
ChatServer.java
import java.util.*;
import java.io.*;
import java.net.*;
class Clients extends Thread
{
private static ArrayList<DataOutputStream> clientOutputStreams;
private DataInputStream dataInputStream;
private DataOutputStream dataOutputStream;
private Socket socket;
static
{
clientOutputStreams=new ArrayList<>();
}
Clients(Socket socket)
{
try
{
this.socket=socket;
this.dataInputStream=new DataInputStream(socket.getInputStream());
this.dataOutputStream=new DataOutputStream(socket.getOutputStream());
clientOutputStreams.add(dataOutputStream);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void run()
{
try
{
try
{
String message=dataInputStream.readUTF();
while(!message.equalsIgnoreCase("quit"))
{
for(DataOutputStream dis:clientOutputStreams)
{
dis.writeUTF(message);
}
message=dataInputStream.readUTF();
}
Thread.currentThread().interrupt();
}
finally
{
dataInputStream.close();
dataOutputStream.close();
clientOutputStreams.remove(clientOutputStreams.indexOf(dataOutputStream));
socket.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
public class ChatServer
{
public static void main(String[] args)throws Exception
{
try
{
ServerSocket serverSocket=new ServerSocket(9000);
while(true)
{
Socket s=serverSocket.accept();
Clients client=new Clients(s);
client.start();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
ChatClient.java
import java.util.*;
import java.io.*;
import java.net.*;
class ReadFromServer extends Thread
{
private DataInputStream readMessage;
ReadFromServer(Socket socket)
{
try
{
this.readMessage=new DataInputStream(socket.getInputStream());
}
catch(Exception e)
{
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
public void run()
{
try
{
while(!Thread.currentThread().isInterrupted())
{
System.out.println(readMessage.readUTF());
}
readMessage.close();
Thread.currentThread().interrupt();
if(Thread.currentThread().isInterrupted())
return;
}
catch(Exception e)
{
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
class WriteToServer extends Thread
{
private DataOutputStream writeMessage;
private String clientName;
private Socket socket;
WriteToServer(Socket socket,String clientName)
{
try
{
this.socket=socket;
this.writeMessage=new DataOutputStream(socket.getOutputStream());
this.clientName=clientName;
}
catch(Exception e)
{
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
public void run()
{
try
{
Scanner scanner=new Scanner(System.in);
String message=scanner.nextLine();
while(!message.equalsIgnoreCase("quit"))
{
writeMessage.writeUTF(clientName+":"+message);
message=scanner.nextLine();
}
writeMessage.writeUTF(message);
writeMessage.close();
Thread.currentThread().interrupt();
if(Thread.currentThread().isInterrupted())
return;
}
catch(Exception e)
{
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
public class ChatClient
{
public static void main(String[] args)
{
try
{
Socket socket=new Socket("localhost",9000);
try
{
System.out.print("Enter Your Name:");
Scanner scanner=new Scanner(System.in);
String clientName=scanner.nextLine();
ReadFromServer rfs=new ReadFromServer(socket);
WriteToServer wts=new WriteToServer(socket,clientName);
wts.start();
rfs.start();
while(wts.isAlive());
rfs.interrupt();
System.out.println("End of Both Threads");
//socket.close();
}
finally
{
socket.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
How to handle such situations when Socket is closed when being used by InputStreamReader
SocketClosedException means that you closed the socket, at writeMessage.close(), and then continued to use it, at readMessage.readUTF(). It's a bug in your code. You will have to sort out which of the reader and writer threads should do the closing, and it should only be one of them, and not while the other is still running.
The EOFException is exactly what you should expect when you call readUTF() on a connection that has already been closed by the peer. Catch it and handle it separately.

Why socket is being closed in run method?

Server:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public final class Server {
public static void main(String[] args) {
new Server().start();
}
public void start() {
ExecutorService executorService = Executors.newFixedThreadPool(10);
try (ServerSocket serverSocket = new ServerSocket(1200)) {
while (true) {
try (Socket socket = serverSocket.accept()) {
executorService.submit(new SocketHandler(socket));
} catch (IOException e) {
System.out.println("Error accepting connections");
}
}
} catch (IOException e) {
System.out.println("Error starting server");
}
}
public final class SocketHandler implements Runnable {
private final Socket socket;
public SocketHandler(Socket connection) {
this.socket = connection;
System.out.println("Constructor: is socket closed? " + this.socket.isClosed());
}
#Override
public void run() {
System.out.println("Run method: is socket closed? " + this.socket.isClosed());
}
}
}
Client:
import java.io.IOException;
import java.net.Socket;
public final class Client{
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 1200)) {
} catch (IOException e) {}
}
Output:
Constructor: is socket closed? false
Run method: is socket closed? true
As you can see from output, when run method is invoked socket is closed, but in constructor it was opened.
Question: How to prevent socket being closed in run method, so that I can access its output stream?
Don't use try with resources with a Socket as the resource, since in this situation since the resource, here the socket, will be closed as soon as the try block exits.

Function call on client connection to server

In socket programming using Java.I want a function call to happen whenever a client connects to the server. I'm stuck up here. Any help will be appreciated.
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class NewConnectionListener implements Runnable{
public static ServerSocket serverSocket;
public NewConnectionListener(){
try {
serverSocket = new ServerSocket(500);
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
while(true){
try {
Socket s = serverSocket.accept();
callMethodWithNewSocket(s);
System.out.println("new Client");
} catch (IOException e) {
System.out.println("Error getting Client");
e.printStackTrace();
}
}
}
}
With this code everytime there is a new connection to port 500 on the server the method callMethodWithNewSocket(Socket s) will be called with the socket as a parameter.

JavaNIO multithreaded server not working

Hello Experts
can somebody please indentify the problem with this server why this is unable to connect more then one client
import java.io.*;
import java.net.*;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.*;
public class MultithreadedServer extends Thread {
private ServerSocketChannel ssChannel;
private Thread tRunSer = new Thread(this, "ServerSelectThread");
public static void main(String argv[]) throws Exception {
new MultithreadedServer();
}
public MultithreadedServer() throws Exception {
this.start();
}
public void run() {
while (true) {
try {
ssChannel = ServerSocketChannel.open();
ssChannel.configureBlocking(false);
int port = 2345;
ssChannel.socket().bind(new InetSocketAddress(port));
} catch (Exception e) {
}
}
}
}
class Connect extends Thread {
private ServerSocketChannel ssChannel;
private SimManager SM;
private BallState BS = new BallState(10, 5);
public Connect(ServerSocketChannel ssChannel) {
this.ssChannel = ssChannel;
SM = new SimManager(BS);
SM.start();
}
public void run() {
try {
SocketChannel sChannel = ssChannel.accept();
while (true) {
ObjectOutputStream oos = new ObjectOutputStream(sChannel
.socket().getOutputStream());
oos.writeObject(BS);
System.out.println("Sending String is: '" + BS.X + "'" + BS.Y);
oos.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
my intention is to send the objects on network.
please help
new code:
import java.io.*;
import java.net.*;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.*;
public class MultithreadedServer extends Thread {
private ServerSocketChannel ssChannel;
private SimManager SM;
private BallState BS = new BallState(10, 5);
private Thread tRunSer = new Thread(this, "ServerSelectThread");
public static void main(String argv[]) throws Exception {
new MultithreadedServer();
}
public MultithreadedServer() throws Exception {
this.start();
}
public void run() {
// create the server socket once
try {
ssChannel = ServerSocketChannel.open();
ssChannel.configureBlocking(false);
ssChannel.socket().bind(new InetSocketAddress(2345));
} catch (IOException e1) {
e1.printStackTrace();
}
while (true) {
// accept new connections on the socket
SocketChannel accept;
try {
accept = ssChannel.accept();
ObjectOutputStream oos;
oos = new ObjectOutputStream(accept.socket().getOutputStream());
oos.writeObject(BS);
System.out.println("Sending String is: '" + BS.X + "'" + BS.Y);
oos.flush();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
You are creating a new server socket for each loop iteration (using the same port over and over). You must create the server socket only once, and then accept new incoming connections.
Something like:
public void run() {
// create the server socket once
ssChannel = ServerSocketChannel.open();
ssChannel.configureBlocking(false);
ssChannel.socket().bind(new InetSocketAddress(2345));
while (true) {
// accept new connections on the socket
try {
SocketChannel accept = ssChannel.accept();
System.out.println("new client: " + accept.getRemoteAddress());
} catch (Exception e) {
System.out.println("exception: " + e.getMessage());
}
}
}
If you put something in your catch block you will probably find it yourself. (e.printStackTracer() might help for the time being).
Here is the reason for your NPE:
If this channel is in non-blocking mode then this method will immediately return null if
there are no pending connections.
This is from ServerSocketChannel.accept().
Your accept call returns null, and you then try to call a method on this null object.

Categories