java sockets address already in use exception - java

I'm facing a strange problem doing java sockets project. Here's my code:
Server:
package second.sockets;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class Server implements Runnable {
public static String HOST = "localhost";
public static int PORT = 1234;
private static final int MAX_USERS = 2;
private static final Server serverInstance = new Server();
private ServerSocket serverSocket;
private List<User> users = new ArrayList<>();
private Server() {
try {
if( this.serverSocket == null ) {
this.serverSocket = new ServerSocket(Server.PORT);
}
} catch(IOException e) {
e.printStackTrace();
System.err.println("could not initialize ServerSocket on port="+Server.PORT +
"["+ e.getMessage() +"]");
}
}
public static Server getInstance() {
return Server.serverInstance;
}
#Override
public void run() {
System.out.println("waiting for incoming connections...");
try {
while( !Thread.interrupted() ) {
this.waitForFreeSlots();
Socket newSocket=null;
try {
newSocket = this.serverSocket.accept();
System.out.println("new connection " + newSocket);
} catch(IOException e) {
System.err.println("could not connect");
}
}
} catch(InterruptedException e) {
System.err.println("server interrupted");
}
}
private synchronized void waitForFreeSlots() throws InterruptedException {
while( this.users.size() >= Server.MAX_USERS ) {
this.wait();
}
}
public static int getPORT() {
return PORT;
}
public static void main(String[] args) {
Server server = Server.getInstance();
Thread serverThread = new Thread(server);
serverThread.start();
}
}
Client:
package second.sockets;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) {
Socket socket=null;
try {
socket = new Socket(Server.HOST, Server.PORT);
} catch(UnknownHostException uhe) {
System.err.println("could not connect to "+Server.HOST+" on port "+Server.PORT+", no such host");
} catch(IOException ioe) {
System.err.println("could not connect to "+Server.HOST + " on port "+Server.PORT);
}
System.out.println(socket);
}
}
I run the server and it works, but when I run a Client I get could not initialize ServerSocket on port=1234[Address already in use: JVM_Bind] and it is from Server code from line 25. It's odd as Server is a singleton so there's no place for more than one instance of the class. What is more I don't even touch it in Client main function. I don't get it, any ideas where the problem is? Thanks.
EDIT:
Here's the stack trace. It comes from Server's constructor although it is private and it shows after running the Client.
java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:382)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)
at java.net.ServerSocket.bind(ServerSocket.java:375)
at java.net.ServerSocket.<init>(ServerSocket.java:237)
at java.net.ServerSocket.<init>(ServerSocket.java:128)
at second.sockets.Server.<init>(Server.java:22)
at second.sockets.Server.<clinit>(Server.java:15)
at second.sockets.Client.main(Client.java:12)
could not initialize ServerSocket on port=21234[Address already in use: JVM_Bind]
Socket[addr=localhost/127.0.0.1,port=21234,localport=53054]
I don't get this transition:
at second.sockets.Client.main(Client.java:12)->at second.sockets.Server.<clinit>(Server.java:15)

The stuff you see in the exception comes from the fact that you are using Server.HOST and Server.PORT in your client code. This calls the class initializer for the Server class. In this initializer all the static stuff in the Server class is created. And I see you have a static Server instance there...so you have in fact several Server instances created.
So avoid using Server.HOST and Server.PORT in the client code and use the real valus directly and it will work.
Normally when you want to share stuff between 2 code entities, move them to a third entity to decouple the server and client. Then let server and client use that new entity.

Okay, I figured out what was wrong. In Client in this line socket = new Socket(Server.HOST, Server.PORT); I was using 2 variables from class Server. When I deleted it and pasted raw values or cahnge the variables to be final, it started to work. This is some wild magic.

Related

How to perform unit test on a server socket?

I am a beginner in Java. I have built a client-server group chat application watching tutorials. I read a lot about unit tests and can implement in simple maths problems but i don't know how does it work out for complex codes. So I want to see a demo of that which will make it easy to understand testing for rest parts. One part of the code is the 'server' class and it is:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
//import java.awt.event.*;
public class Server {
private final ServerSocket s;
public Server(ServerSocket serverSocket)
{
this.s = serverSocket;
//this.display = display;
}
public void startServer() {
try {
// Listen for connections (clients to connect) on port 1234.
while (!s.isClosed()) {
// Will be closed in the Client Handler.
Socket socket = s.accept();
System.out.println("A new client has connected!");
ClientHandler clientHandler = new ClientHandler(socket);
Thread thread = new Thread(clientHandler);
// The start method begins the execution of a thread.
// When you call start() the run method is called.
// The operating system schedules the threads.
thread.start();
}
} catch (IOException e) {
closeServerSocket();
}
}
// Close the server socket gracefully.
public void closeServerSocket() {
try {
if (s != null) {
s.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
// Run the program.
public static void main(String[] args) throws IOException {
ServerSocket s = new ServerSocket(1234);
Server server = new Server(s);
server.startServer();
}
}
and the test I want to perform are:
import static org.junit.Assert.*;
public class ServerTeste {
#org.junit.Test
public void startServer() {
}
#org.junit.Test
public void closeServerSocket() {
f
}
}
#org.junit.Test
public void main() {
}
}
NB: Apologies for any mistake because I am complete beginner.
Start the server in a separate thread, and connect to it like you would normally do

Java RMI: how to make client stub method called on server print message on client screen?

I'm making a chat with rmi in Java. I have one server object and at least two clients objects. When a client send a message to the server calling the method recebeMensagem remotely, the server must print that message on all clients' screen (except the client that sent the message).
The client class has a method printMenssagem(Mensagem msg), that is called remotely by the server. The problem is that that method is printing on server's screen. How do I make to print the message on client's screen instead?
Server.java:
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.function.Predicate;
public class Server implements ChatServer {
private ArrayList<String> listaClientes = new ArrayList<>();
private static int port = 5002;
public static void main(String[] args) {
try {
Server obj = new Server();
ChatServer stub = (ChatServer)
UnicastRemoteObject.exportObject(obj, port);
// Bind the remote object's stub in the registry
Registry registry = LocateRegistry.createRegistry(port);
registry.bind("chat", stub);
System.out.println("Server ready!");
} catch (Exception e) {
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}
#Override
public void adicionaCliente(String user) {
this.listaClientes.add(user);
}
#Override
public void retiraCliente(String userName) {
Predicate<String> clientePredicate = cp ->
cp.equals(userName);
listaClientes.removeIf(clientePredicate);
try {
Registry registry = LocateRegistry.getRegistry(port);
registry.unbind(userName);
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
#Override
public void recebeMensagem(Mensagem msg) {
try {
Registry registry = LocateRegistry.getRegistry(port);
for(String cliente : listaClientes) {
if (!cliente.equals(msg.getRemetente())) {
Client stub = (Client) registry.lookup(cliente);
stub.printMensagem(msg);
}
}
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
public ArrayList<String> getListaClientes() {
return listaClientes;
}
public void setListaClientes(ArrayList<String> listaClientes) {
this.listaClientes = listaClientes;
}
}
Client.java :
import java.io.Serializable;
import java.rmi.Remote;
public class Client implements Remote, Serializable {
private static final long serialVersionUID = 6864579049922061838L;
private static int port = 5002;
private static String host = "127.0.0.1";
public static void main(String[] args) {
new Thread(new ClientInterface(host, port)).start();
}
public void printMensagem(Mensagem mensagem) {
System.out.println(mensagem.getRemetente() + ": " + mensagem.getMensagem());
}
}
how to make client stub method called on server print message on client screen?
The client doesn't have a stub. It isn't a remote object. It is a serializable object and it has been transported to the Registry holus bolus, and it runs in whatever JVM performed the Registry.lookup() to obtain it. This is not what you want. You want it to be a remote object, with a stub, so you have to make it implement a remote interface, and export it, and use it via its remote interface at the peer.
You also need to be aware that your present architecture won't work across more than one host, as you can't bind to a remote Registry. You will need to add a client registration method to the server.

Jetty Websocket server is working locally, but remote connections fail with "Host is down" error, how to fix it?

I'm running a websocket server, using embedded Jetty.
It works as intended when I make connections from the same machine (localhost), but when I try to connect from a different machine, I get the error "Host is down" (also known as EHOSTDOWN).
Logs say that Jetty is listening on 0.0.0.0 address, so it should accept connections from everywhere, and the port (in this example, 12345) is allowed in ufw for all protocols. I also tried temporarily disabling ufw and that had no effect.
This is my code (this is a simple websocket echo-server, I've removed everything that's irrelevant):
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
import java.io.IOException;
public class EchoServerLauncher {
static final int PORT = 12345;
public static void main(String[] args) {
startServer(PORT);
}
private static void startServer(final int port) {
new EchoServer(port).startAndJoin();
}
}
class EchoServer extends WebsocketServerBase {
static final String PATH = "/hello/";
public EchoServer(final int port) {
super(port);
}
void startAndJoin() {
super.startAndJoinWithServlet(new EchoServlet(), PATH);
}
}
class EchoServlet extends WebSocketServlet {
#Override
public void configure(final WebSocketServletFactory factory) {
factory.setCreator((req, resp) -> new EchoSocketAdapter());
}
}
class EchoSocketAdapter extends WebSocketAdapter {
#Override
public void onWebSocketText(final String message) {
super.onWebSocketText(message);
if (message == null) return;
try {
getSession().getRemote().sendString(message);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
class WebsocketServerBase {
private final int port;
public WebsocketServerBase(int port) {
this.port = port;
}
void startAndJoinWithServlet(WebSocketServlet servlet, String path) {
final Server server = new Server();
final ServerConnector connector = new ServerConnector(server);
connector.setPort(this.port);
server.addConnector(connector);
final ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
contextHandler.setContextPath("/");
server.setHandler(contextHandler);
final ServletHolder servletHolder = new ServletHolder(servlet.getClass().getSimpleName(), servlet);
contextHandler.addServlet(servletHolder, path);
try {
server.start();
server.dump(System.err);
server.join();
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
}
So, what could cause such issue? I don't even know anything else to try…
It was my stupidity, I forgot to allow that port on my client's router. (Too bad I cannot delete close the question).

TcpSockets do not connect

I am trying to establish a TCP connection between a laptop as a client and a pc as a server.
My goal is to use the server to send messages between two android devices. The server has a public IP address. To test the connection, I have written two simple Java classes:
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public ServerSocket welcome;
public Socket soc;
public int listeningPort = /* default port */;
public TcpServer() {
}
public static void main(String[] args) {
TcpServer ms = new TcpServer();
if(args.length > 0) {
ms.listeningPort = Integer.parseInt(args[0]);
}
ms.listen();
}
public void listen() {
try {
welcome = new ServerSocket(listeningPort);
System.out.println(">>> listening on port " + listeningPort + " <<<");
soc = welcome.accept();
System.out.println(">>> got a new connection from "
+ soc.getInetAddress().toString() + " <<<");
while (true) {
try {
byte b[] = new byte[1024];
soc.getInputStream().read(b, 0, 1);
System.out.print((char) (b[0]));
} catch (Exception e) {
System.err.println(e);
}
}
} catch (Exception e) {
System.err.println(e);
}
}
}
import java.net.Socket;
public class TcpSendClient {
private String serverIp = /* some ip */;
public int port = /* default port */;
private SendThread st;
public TcpSendClient() {
}
public static void main(String[] args) {
TcpSendClient client = new TcpSendClient();
if(args.length > 0) {
client.port = Integer.parseInt(args[0]);
}
client.send();
}
public void send() {
System.out.println("Try to connet to " + serverIp + " via Port" + port);
st = new SendThread(serverIp, port);
st.start();
}
class SendThread extends Thread {
private Socket soc;
public SendThread(String theIp, int thePort) {
try {
soc = new Socket(theIp, thePort);
} catch (Exception e) {
System.err.println(e);
}
}
public void run() {
try {
while (true) {
String toSend = "Hello ";
soc.getOutputStream().write(toSend.getBytes());
Thread.sleep(800);
System.out.println("sent");
}
} catch (Exception e) {
System.err.println(e);
}
}
}
}
When I run both Java files on the server pc, the connection works fine. It also worked if I set up a local Wi-Fi with one laptop and connect to it using another laptop.
But, when I run the client file from a laptop connected to the internet, I am not able to get a connection.
In the firewall on the Server, I opened a number of ports for the connection and the laptop I use as a client has the firewall disabled.
Apart from the firewall, I do not really know what to look into in order to get the connection running. Any ideas as to the cause of my problem and a solution?
I found the solution: The windows firewall was still blocking the ports for Java. It took me a little longer to figure this out, because I was not registered as admin on that pc and could not see the rules.

NullPointerException in Thread's run method

I would really appreciate help with my program. It is some sort of chat server with multiple clients.
Here's the server code:
package com.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static int PORT;
private ServerSocket server;
private Socket socket;
public Server(int port) throws IOException {
PORT = port;
server = new ServerSocket(PORT);
System.out.println("server started");
try {
while (true) {
socket = server.accept();
try {
new ServeClient(socket);
} catch (IOException e) {
socket.close();
}
}
} finally {
server.close();
}
}
public static void main(String[] args) throws IOException {
int port = Integer.parseInt(args[0]);
Server server = new Server(port);
}
}
I start the server and then create a Client. The server receives connection socket from socket
and creates a ServeClient Thread.
Here's ServeClient code:
package com.server;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Enumeration;
import java.util.Vector;
import com.gui.WindowManager;
public class ServeClient extends Thread {
private final Socket socket;
private BufferedReader in;
private PrintWriter out;
private String msg;
public static final String ENDSTRING = "END";
public static Vector clients = new Vector();
public ServeClient(final Socket socket) throws IOException {
this.socket = socket;
System.out.println("socket " + socket);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream())), true);
start();
}
public void run() {
try {
clients.add(this);
while (true) {
msg = in.readLine();
if (msg == ENDSTRING)
break;
broadcast(msg);
}
System.out.println("closing...");
} catch (IOException e) {
System.err.println("IO EXCEPTION");
} finally {
try {
socket.close();
} catch (IOException e) {
System.err.println("SOCKET NOT CLOSED");
}
}
}
#SuppressWarnings("deprecation")
public void broadcast(String msg) {
synchronized (clients) {
Enumeration<ServeClient> e = clients.elements();
while (e.hasMoreElements()) {
ServeClient serveClient = e.nextElement();
try {
synchronized (serveClient.out) {
serveClient.out.println(msg);
}
} catch (Exception eee) {
serveClient.stop();
}
}
}
}
}
What i get is a NullPointerException when ServeClient invokes run() method
server started
socket Socket[addr=/127.0.0.1,port=51438,localport=8888]
Exception in thread "Thread-0" java.lang.NullPointerException
at com.server.ServeClient.run(ServeClient.java:33)
line 33 is the line with first "try" statement in ServeClient run() method
com.server.ServeClient.run(ServeClient.java:33)
I don't believe that it's happening at the try.
Open up an IDE, turn on debugging, and step through until you can see what's happening. That's the fastest way to figure out what you've missed.
There's an object that you're assuming is fine that is not. Find it.
Here's an example of how to do this properly:
http://www.kodejava.org/examples/216.html
Your problem is with the order in which static instance variables are initialised. Try doing something like:
...
private static Vector clients = null;
...
if (clients==null) {
clients = new Vector(); // consider putting this in a synchronized block
}
before you add the client to the vector.
Sorry for necroing such an old issue but it seemed like this problem wasn't resolved, so I'll give a bit of input from my end.
I've had a similar problem and the compiler also kept telling me that the problem was at the start() method. However, when I commented out the thread part and just ran the code on the same thread as the UI, the compiler directed me to the real source of the problem: the code inside the thread.
After making sure the code didn't give an error, I enclosed the code with the original thread code, and it stopped giving me the NullPointerException error.
Hope this helps someone along the way.
Remove the duplicate class declaration in JPanel.
I was trying to run a timer thread that updated a clock in the main application window.
I had created the JFrame with Eclipse/WindowBuilder and had followed a tutorial on how to make a timer. I had copied the declaration of the textfield into the class declaration to make it available for the entire class, but forgot to remove the Class Id in front of the widget definition. So it still initialized the local instance and not the global one. Thus when I accessed the global one it was still null.

Categories

Resources