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;
Related
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);
I have a thread that is listening to a UDP server. It works well unless (1) the UDP server is started after my application, or (2) the UDP server is restarted while my application is running. In either of those cases, my listener will not connect to the server any more.
It seems stuck in the awaitRequests() method, but I am not for sure.
Where is the code breaking?
package myPackage;
public class UDPServerListener implements Runnable {
private volatile boolean run = true;
private byte[] receiveBuffer;
private int receiveBufferSize;
private InetSocketAddress myInetSocketAddress;
private DatagramSocket myDatagramSocket;
private DatagramPacket myDatagramPacket;
#Override
public void run() {
try {
// Create and bind a new DatagramSocket
myDatagramSocket = new DatagramSocket(null);
myInetSocketAddress = new InetSocketAddress(123456);
myDatagramSocket.setReuseAddress(true);
myDatagramSocket.bind(myInetSocketAddress);
// Set-up the receive buffer
receiveBuffer = new byte[2047];
myDatagramPacket = new DatagramPacket(receiveBuffer, 2047);
awaitRequests(myDatagramSocket, myDatagramPacket);
} catch (SocketException se) {
} catch (IOException ioe) {
} catch (InterruptedException ie) {
}
}
private void awaitRequests(DatagramSocket myDatagramSocket, DatagramPacket myDatagramPacket) throws SocketException, IOException, InterruptedException{
int maxRetries = 5;
while (run){
try {
myDatagramSocket.receive(myDatagramPacket);
byte[] data = myDatagramPacket.getData();
maxRetries = 5;
process(data);
} catch (SocketException se){
maxRetries--;
if(maxRetries == 0) throw se;
Thread.currentThread().sleep(5000);
reconnect(myDatagramSocket);
}
}
}
private void process(byte[] data) throws SocketException {
receiveBufferSize = myDatagramPacket.getLength();
// Do stuff with the received data ...
myDatagramPacket.setLength(2047);
}
private void reconnect(DatagramSocket myDatagramSocket) throws SocketException{
myDatagramSocket.bind(myInetSocketAddress);
}
public boolean isRun() {
return run;
}
public void setRun(boolean run) {
this.run = run;
}
}
First of all:
myInetSocketAddress = new InetSocketAddress(123456);
is invalid, the max port number is 65535, so you're creating an invalid address.
I would go for something more like this:
public class TestUdp {
public static void main( String[] args )
{
boolean run = true;
DatagramSocket sock = null;
try {
sock = new DatagramSocket(50001);
} catch (SocketException e) {
e.printStackTrace();
return;
}
byte[] buff = new byte[2000];
DatagramPacket dp = new DatagramPacket(buff, buff.length);
while (run) {
try {
sock.receive(dp);
} catch (IOException e) {
break;
}
dp.getData();
System.out.println("Received: " + dp.getLength() + " bytes");
}
}
}
The DatagramSocket constructor already binds to the port and there is no need to do "reconnect()" like you did, as UDP si not connected, once you have a process bound to a UDP port, it's there.
I'm currently developing a TicTacToe multithreaded networked game for my university and I'm stuck on an annoying problem.
I wish that my server accepts 2 connections each time and then waits for other 2 connections etc.
The problem is that, in my code, if a client connects to the server and closes the connection while the second client is not yet connected to the server, the second client is not able to play because it "thinks" that the first client is connected and ready.
I thought to do something like this but I can't find a way to actually implement it.
The server is structured in 3 classes:
TTT_Server (which cointains the main method and launches threads);
TTT_ServerThread (which contains the thread(s) behaviour);
TTT (which contains the TicTacToe board and some method).
TTT_Server class:
public class TTT_Server()
{
private static ServerSocket serverSocket;
private static boolean running = true;
public static void main(String[] args)
{
try
{
// creazione ServerSocket sulla porta 8089
serverSocket = new ServerSocket(8089);
System.out.println("Server Socket creata e in ascolto sulla porta 8089");
while(running)
{
TTT ttt = new TTT();
Socket socket1 = serverSocket.accept();
Socket socket2 = serverSocket.accept();
TTT_ServerThread st1 = new TTT_ServerThread(socket1, 1, ttt, socket2);
TTT_ServerThread st2 = new TTT_ServerThread(socket2, 2, ttt, socket1);
st1.start();
st2.start();
System.out.println("thread lanciati");
}
}
catch(IOException e)
{
System.out.println(e);
running = false;
}
finally
{
try
{
serverSocket.close();
}
catch (IOException e)
{
System.out.println(e);
}
}
}
}
(a part of) TTT_ServerThread class:
private Socket socket;
private Socket socketOtherPlayer;
private BufferedReader in;
private PrintWriter out;
private PrintWriter outOtherPlayer;
private TTT TicTacToe;
private int player;
private boolean fineGioco;
private int counter = 0;
public TTT_ServerThread(Socket socket, int num_connessione, TTT ttt, Socket socketOtherPlayer)
{
this.socket = socket;
this.socketOtherPlayer = socketOtherPlayer;
this.player = num_connessione;
this.TicTacToe = ttt;
try
{
this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.out = new PrintWriter(socket.getOutputStream());
this.outOtherPlayer= new PrintWriter(socketOtherPlayer.getOutputStream());
}
catch(IOException e)
{
System.out.println(e);
}
}
#Override
public void run()
{
//[...]
}
(a part of) TTT class:
public class TTT
{
private int[] board = new int[9];
private int turno = 1;
public TTT()
{
for (int i = 0; i < 9; i++)
board[i] = 0;
}
protected synchronized void setBoard(int locazioneMossa, int giocatore)
{
board[locazioneMossa] = giocatore;
}
protected synchronized int getBoard(int locazioneMossa)
{
return board[locazioneMossa];
}
protected synchronized void setTurno(int turnoRicevuto)
{
turno = turnoRicevuto;
}
protected synchronized int getTurno()
{
return turno;
}
//[...]
}
Is there a way to implement a sort of that diagram that i thought?
Thank you all in advance for the help! And sorry for my English, it's not my primary language.
Instead of trying to "accept two connections at a time", you should accept one connection at a time. If there's no waiting connection, the connection should be put to a waiting list. If there is a waiting connection, pair them up.
That way you'll have a single accept() per loop, but 2 possible ways to handle them.
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.
I want to create chat-server which would handle 100-500 users in different rooms.
I decided to use Netty framework, because of event-based arcitecture (which is very familiar to me). I started with small server which respond "NYA" for everything it recieve.
main:
public class ChatServer{
public static void main(String[] args) throws Exception {
ExecutorService bossExec = new OrderedMemoryAwareThreadPoolExecutor(1, 400000000, 2000000000, 60, TimeUnit.SECONDS);
ExecutorService ioExec = new OrderedMemoryAwareThreadPoolExecutor(4 /* число рабочих потоков */, 400000000, 2000000000, 60, TimeUnit.SECONDS);
ChannelFactory factory = new NioServerSocketChannelFactory(bossExec,ioExec);
ServerBootstrap bootstrap = new ServerBootstrap(factory);
bootstrap.setPipelineFactory(new ChannelPipelineFactory(){
public ChannelPipeline getPipeline(){
return Channels.pipeline(new ChatChannelHandler());
}
});
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.keepAlive", true);
bootstrap.setOption("reuseAddress", true);
bootstrap.bind(new InetSocketAddress(5555));
System.out.println("ChatServer started at last...");
}
}
handler:
public class ChatChannelHandler extends SimpleChannelUpstreamHandler {
private final ChannelBuffer messageBuffer = ChannelBuffers.dynamicBuffer();
private boolean processingMessage = false;
private short messageLength;
#Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("Connection from: " + e.getChannel().getRemoteAddress().toString());
}
#Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
e.getChannel().write(ChannelBuffers.copiedBuffer("NYA!", "UTF-8");
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
System.out.println("Exception: " + e.getCause());
Channel ch = e.getChannel();
ch.close();
}
}
I use simulation program which creates N connections and then randomly write stuff to server with 1-5 second pause. Then i connect with my Flash-based client, to see how it is working. So problem is that under 10-90 connections my flash client immediately get responds from the server, but when number of simulated connections exceed 100 my flash client remain silent. I simply don't understand why.
I figured out, that all messages from my 100+ client gets into buffer, but messageReceive event simply not fired for them. Looks like event queue reachs some limit of registered events, or something like that.
It's really sadden me, because i read about even simpler servers handles 1k+ request per second.
I work under Windows 7, if it is necessary. Also my server never use more then 2-3% of CPU.
My simulation generator:
public class ClientLoadEmulation implements Runnable {
private String host;
private int port;
private static final int minStringLength = 5;
private static final int maxStringLength = 40;
private static final int minPause = (int) (1 * 1000);
private static final int maxPause = (int) (5 * 1000);
Random rand = new Random();
public ClientLoadEmulation(String host, int port, int numThreads) {
this.host = "192.168.0.100";
this.port = 5555;
for (int i = 0; i < numThreads; ++i) {
new Thread(this).start();
try {
Thread.sleep(100);
} catch (Exception ex) {
}
}
}
#Override
public void run() {
byte buffer[] = new byte[255];
try {
Socket s = new Socket(host, port);
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
while (true) {
String govno = "";
...STRING GENERATION STUFF CUTTED...
ByteBuffer LENGTH_BUFFER = ByteBuffer.allocate(2);
LENGTH_BUFFER.putShort((short) govno.length());
LENGTH_BUFFER.flip();
out.write(LENGTH_BUFFER.array());
out.write(govno.getBytes("UTF-8"));
//System.out.println(Thread.currentThread() + " wrote " + govno);
int pause = minPause
+ (int) (rand.nextDouble() * (maxPause - minPause));
try {
Thread.sleep(pause);
} catch (InterruptedException ie) {
}
}
} catch (IOException ie) {
System.out.println("ERROR: " + ie.getMessage());
}
}
static public void main(String args[]) throws Exception {
new ClientLoadEmulation("127.0.0.1", 5555, 100);
}
}
(Sorry for my English skills)
I'm not sure about your sample, but when I tried to run ChatServer you provided, it was not waiting for the client conneciton, but rather quit.
Moreover I don't see there port 5555 setup at all (the one expected from the client).
Please post the working sample to check.