Limit number of connection for ServerSocket - java

I'm new in Networking and I'm trying to make a small java application for chatting.
What I want is the ServerSocket to accept one and only one connection.If a second Socket tries to connect to the ServerSocket it will throw an exception so the user who launched the socket knows that he can't connect to that ServerSocket
I looked at the javadoc and I've found that constructor.
public ServerSocket(int port, int backlog) throws IOException
Creates a server socket and binds it to the specified local port number, with the specified backlog. A port number of 0 means that the port number is automatically allocated, typically from an ephemeral port range. This port number can then be retrieved by calling getLocalPort.
and I tried this
class Service implements Runnable {
private Socket maChaussette;
Service(Socket s) {
maChaussette = s;
}
public void run() {
System.out.println("connection established");
while (true) {
System.out.print("");
}
//maChaussette.close();
}
}
Server :
class Serv {
public static void main(String[] a) throws IOException {
ServerSocket socketAttente;
socketAttente = new ServerSocket(11111, 1);
boolean conn = false;
Thread t;
while (true) {
Socket s = socketAttente.accept();
t = new Thread(new Service(s));
t.start();
}
//socketAttente.close();
}
}
client
public class Cll {
public static final int PORT = 11111;
public static void main(String[] arguments) {
try {
Socket service = new Socket("localhost", PORT);
while (true) {
System.out.print("");
}
} catch (Exception e) {
System.err.println("Error");
e.printStackTrace();
System.exit(1);
}
}
}
I don't try to communicate or something, I just made these classes to try to block the number of connections to the ServerSocket.
But with that code if I run two Cll program I got two times the message "connection established ".
does Anybody have an idea about how to proceed to limit connections on a ServerSocket ?

Just close the ServerSocket after you accept one connection. And get rid of the 'while (true)' around the accept loop.

Related

Why I try to run Client.jar on Another Computer but receive Connection refused" or "Connection timed out

I spent more than one day , but still can't figure out how can I resolve the problem. Every time I shut down the firewall on my server, my other computer can successfully run Client.jar.
I check the firewall on my server PC. I am sure I opened the port "4888" and "6151", but still can't run normally.
I don't know how "W.getSocketFactory()" works.
System.out.println("創造"+ W.getSocketFactory()); → 創造 null (Is it an issue?)
Is there some problems on my codes or somethings?
Below is my server code:
public class RemoteServer extends UnicastRemoteObject implements MyRemote{
public static void main(String[] args)
{
try {
RMILocalSocketFactory W = new RMILocalSocketFactory(6151);
System.out.println("創造"+ W.getSocketFactory());
RMISocketFactory.setSocketFactory(W);
LocateRegistry.createRegistry(4888);
System.setProperty("java.rmi.server.hostname","175.183.49.139");
MyRemote Server = new RemoteServer();
Naming.rebind("rmi://175.183.49.139:4888/Remote_Hello!", Server);
} catch (Exception e) {
e.printStackTrace();
}
}
RemoteServer() throws RemoteException {}
public String SayHello()
{
System.out.println("RMI Connection");
return "you Connected Server\n" + "Server says , Hey!";
}
}
class RMILocalSocketFactory extends RMISocketFactory {
private int dataPort;
public RMILocalSocketFactory(int dataPort1){
this.dataPort = dataPort1;
}
public Socket createSocket(String host, int port) throws IOException {
String a = "175.183.49.139";
Socket check = new Socket(a = host, port);
return check;
}
public ServerSocket createServerSocket(int port) throws IOException {
return new ServerSocket(port);
}
}
(Client) the one part of code:
try {
LocateRegistry.getRegistry(4888);
MyRemote Service = (MyRemote)Naming.lookup("rmi://175.183.49.139:4888/Remote_Hello!");
String Say= Service.SayHello();
Area.append(Say);
} catch (Exception e) {
e.printStackTrace();
}
```[Problem Picture:][1]
[1]: https://i.stack.imgur.com/LkK5T.jpg
I resolved my problem by myself.
I finally found my java.exe on firewall is blocked.
That is the reason why I can't receive another request while firewall is on.
And make sure both port must be open on firewall as well.

Terminating the older instance of a program if a newer instance is started

Scenario: A program starts a server and listens for another program to connect to said server; if another program connects, kill the server on the old program and start the same server on the new program, and repeat the cycle.
After running the program for the first time, I get:
thread started
attempting connection
server started
Then, after running the program again, the first instance reads:
thread started
attempting connection
server started
Another instance was started, this instance has been shut down
Exception in thread "Thread-0" java.lang.NullPointerException
at me.aj.phoenix.util.JustOneServer.startServer(JustOneServer.java:37)
at me.aj.phoenix.util.JustOneServer.run(JustOneServer.java:28)
and the second instance reads:
attempting connection
Another instance was running and has been closed.
server started
java.net.BindException: Address already in use: NET_Bind
at java.base/java.net.PlainSocketImpl.bind0(Native Method)
at java.base/java.net.PlainSocketImpl.socketBind(PlainSocketImpl.java:132)
at java.base/java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:436)
at java.base/java.net.ServerSocket.bind(ServerSocket.java:381)
at java.base/java.net.ServerSocket.<init>(ServerSocket.java:243)
at java.base/java.net.ServerSocket.<init>(ServerSocket.java:187)
at me.aj.phoenix.util.JustOneServer.startServer(JustOneServer.java:34)
at me.aj.phoenix.util.JustOneServer.run(JustOneServer.java:26)
Essentially what im trying to do is whenever a new version of the program is started, close the older program and start the listener on the newer program
Here is the code:
public class TestProgram extends Thread {
public final int port = 9665;
ServerSocket serverSocket = null;
Socket clientSocket = null;
#Override
public void run() {
System.out.println("thread started");
try {
this.check();
this.startServer();
} catch (IOException ioe) {
this.startServer();
}
}
public void startServer() {
try {
System.out.println("server started");
serverSocket = new ServerSocket(port, 1);
clientSocket = serverSocket.accept();
Logger.print("Another instance was started, this instance has been shut down");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
}
public void check() throws UnknownHostException, IOException {
System.out.println("attempting connection");
Socket socket = new Socket("localhost", port);
if(socket.isConnected()) {
Logger.print("Another instance was running and has been closed.");
}
}
}
The second program is not waiting for the first programs listening server to unbind from the port, and I'm not quite sure how to fix it.
The main problem is that the logic in startServer method should run in an infinite loop to account for the weak nature of sockets that may be disconnected at any time, and more importantly for the scenario in which is trying to connect to a port that is bound by a previous instance that is in the process of shutting down.
while (true)
runServer(port);
Other problems include closing resources when problems arise and nesting away the exceptions that arise from a client Socket from those that come from a ServerSocket; so that whenever an exception is thrown for a ServerSocket is not interpreted as an exception that would end the execution of startServer method.
void runServer(int port) {
try (ServerSocket serverSocket = new ServerSocket(port, 1)) {
logger.debug("Server started!");
try (Socket clientSocket = serverSocket.accept()) {
logger.debug("Signal to shutdown received. Shutting down.");
System.exit(0);
}
} catch (IOException e) {
logger.debug("The other application is still shutting down...");
}
}
The following is a complete working example of this:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ServerReplacer {
private static Logger logger = LoggerFactory.getLogger(ServerReplacer.class);
public static void runReplacerService(int port) {
searchOlderInstances(port);
logger.debug("Server starting...");
while (true)
runServer(port);
}
private static void searchOlderInstances(int port) {
logger.debug("Attempting to find older instance...");
try (Socket socket = new Socket("127.0.0.1", port)) {
logOtherInstanceFound(socket.isConnected());
} catch (Exception e) {
logOtherInstanceFound(false);
}
}
private static void logOtherInstanceFound(boolean otherInstanceFound) {
logger.debug(otherInstanceFound ?
"FOUND ANOTHER INSTANCE RUNNING! It has been signaled to shut down." :
"No older instance found.");
}
private static void runServer(int port) {
try (ServerSocket serverSocket = new ServerSocket(port, 1)) {
logger.debug("Server started!");
try (Socket clientSocket = serverSocket.accept()) {
logger.debug("Signal to shutdown received. Shutting down.");
System.exit(0);
}
} catch (IOException e) {
logger.debug("The other application is still shutting down...");
}
}
public static void main(String[] args) {
runReplacerService(9665);
}
}
Complete code on GitHub
Hope this helps.

Open two ports connection with one server on java

I would like to launch a server who listens simultaneously to two different ports and with a different treatment to incoming connections (I launch a differnet slave depending on port). I did something like this:
public class ServeurMaitre {
public static ServerSocket serverSocket = null;
int poolSize = 15;
private ExecutorService pool = null;
ServeurMaitre(int port, int size){
try {
serverSocket = new ServerSocket(port, size);
pool = Executors.newFixedThreadPool(poolSize);
System.out.println("Serveur en marche. En attente des clients");
} catch (IOException ex) {
Logger.getLogger(ServeurMaitre.class.getName()).log(Level.SEVERE, null, ex);
}
}
void ConnexionServeur() throws IOException {
while(true) {
Socket cnx = serverSocket.accept();
if (cnx.getLocalPort()==3333) {
pool.execute(new EsclaveXML(cnx, this));
}
if(cnx.getLocalPort()==8000) {
pool.execute(new EsclaveHTTP(cnx, this));
}
}
}
public class Main{
public static void main(String[] args) throws IOException {
ServeurMaitre serveur = new ServeurMaitre(8000, 1);
ServeurMaitre serveur1 = new ServeurMaitre(3333, 1);
serveur.Initialisation();
serveur.ConnexionServeur();
serveur1.ConnexionServeur();
}}
Problem: connexions that arrive on port 3333 are well treated but those who are on 8000 don't.
Any help please? Thank you.
I think, cause of the problem is "static serverSocket" variable.
You can change this line
public static ServerSocket serverSocket = null;
to
public ServerSocket serverSocket = null;

Java: How can I create an application that will only start if an instance of it doesn't exist and call the instance if it does exist?

I am trying to create a program with Java that can only have one instance of it running at a time.
I am using Sockets and ServerSockets to try to achieve this.
How the program is supposed to work is:
The main method will check if any parameters have been passed, it will try to write the first parameter to the server, if it fails that means, that means that this is the only running instance, so it will open the ServerSocket and then start the frame. If it doesn't fail then the application is already running so it should send the string and the other instance should be able to read it and process it.
Here's the main method:
public static void main(String[] args) {
String fileName = null;
if (args.length >= 1) {
fileName = args[0];
}
if (Singleton.sendSignal(fileName)) {
Frame.getFrame().open(fileName);
Singleton.checkInput();
}
}
And here's the server class:
public class Singleton {
private static final int portNumber = 4243;
private static ServerSocket serverSocket;
private static Socket clientSocket;
private static Socket echoSocket;
public static boolean sendSignal() {
try {
echoSocket = new Socket(InetAddress.getLocalHost().getHostName(), portNumber);
PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
out.write("Open\n");
out.close();
close();
return false;
} catch (Exception e) {
close();
return true;
}
}
public static void checkInput() {
try {
renewReader();
} catch (Exception e) {
close();
}
}
public static void renewReader() throws Exception {
serverSocket = new ServerSocket(portNumber);
clientSocket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine = in.readLine();
if (inputLine.equals("Open")) {
Widget.getInstance().setVisible(true);
}
close();
renewReader();
}
public static void close() {
try {
serverSocket.close();
} catch (Exception e) {
}
try {
clientSocket.close();
} catch (Exception e) {
}
try {
echoSocket.close();
} catch (Exception e) {
}
}
}
Although half of this code works (only one instance runs at a time), only the first set of data are being passed and then the program stops reading. How can I make the socket listen until the program is closed?
I your checkInput() method, you are accepting for client connection once here. Try something like this:
public static void checkInput()
{
//do something here
serverSocket = new ServerSocket(portNumber);
//wait for request from client.
Socket clientSocket = serverSocket.accept();
//
// do your processing here
// call checkInput method again.
checkInput();
}
As soon as another instance it started, server will accept the request, do the processing and then again starts waiting for more requests (for this we called cehckInput again).
Also in your main() add this:
public static void main(String[] args)
{
String fileName = null;
if (args.length >= 1) {
fileName = args[0];
}
if (Singleton.sendSignal(fileName))
{
Frame.getFrame().open(fileName);
// start the server in a thread so that main method can continue on
new Thread()
{
public void run()
{
Singleton.checkInput();
}
}.start();
}
// do your other tasks.
}
On upon termination of program, your sockets will auto close. Also if you want to explicitly close the sockets, you can add a shutdown hook to close it.
A simple hook looks like this.
Runtime.getRuntime().addShutdownHook(your thread that will close sockets);

How to handle the number of threads in a client-server java app?

As the title suggests, I'm implementing a small project which allows clients to connect to server using multi-Threading to manage the connections. I would like to limit the connections and when the Server is full of requests, the other clients should be put in a queue, ex: the server only allows 2 clients to connect the server at the same time, the other clients until their turn.
This is my Server class
public class Server {
static BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
//Declare an instance of CommandParameter class
static CommandParameter par;
//Initialize a BufferedReader and BufferedWriter
static BufferedReader bufferedReader;
static BufferedWriter bufferWriter;
//
static int port;
static String serverData;
static int proc_count;
private static String command;
public static void main(String[] args) throws Exception {
command = userInput.readLine();
System.out.println("Server is available");
//Thread.sleep(2000);
processCommand(command);
startServer(port);
}
public static void startServer(int port) {
ServerSocket serverSocket = null;
try {
//create a port for server in order to listen incoming connections
serverSocket = new ServerSocket(port);
//allow client connect to server
} catch (IOException e) {
System.out.println(e);
}
while (true) {
try {
new ThreadSocket(serverSocket.accept(),serverData).start();
} catch (IOException ex) {
System.out.println("Server starts fail");
}
}
}
public static void processCommand(String input) {
//assign the user input to an String array
String inputLine = input;
int commandCount = checkCommand(inputLine);
if(commandCount>3 || commandCount ==-1){
System.out.println("Invalid command");
System.exit(1);
}
//assign the user input to an String array
String[] command = inputLine.split(" ");
par = new CommandParameter();
//JCommander parses the command to get the pairs parameter name and value
JCommander jc = new JCommander(par, command);
port = par.getPort();
serverData = par.getServerdata();
proc_count = par.getProc_count();
}
public static int checkCommand(String inputLine) {
int count = 0;
if (inputLine.contains("-port")) {
count++;
}else if (inputLine.contains("-data")) {
count++;
} else if (inputLine.contains("-proc_count")) {
count++;
} else{
return -1;
}
return count;
}
}
any ideas?
This is exactly where asynchronous IO becomes most useful. [large number of IO requests need to be handled by limited number of worker threads]. There are system calls in most of the modern operating systems allowing asynchronous IO operations. example, epoll in linux, IOCP in Windows, AIX and Solaris, KQueue in BSD flavors and Mac OS. In java, native non blocking calls are abstracted behind different SPIs - examples - sun.nio.ch.WindowsSelectorImpl, sun.nio.ch.KQueueSelectorImpl , sun.nio.ch.EPollSelectorImpl etc.
What I recommend you to use is Netty.
An example of servicing a large number of HTTP requests with using a smaller fixed number of threads is a simple task using netty API.
Sample bootstrap code with one listener thread and two workers will look like
public static void setupHTTPListeners()
{
ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newFixedThreadPool(1),
Executors.newFixedThreadPool(2)));
-----
-----
}
On the same context, one of the most popular read is here - The C10k problem.
Use ServerSocket(int port, int backlog); the backlog parameter is the maximum number of connections allowed.

Categories

Resources