Best way to handle many clients (with threads?) - java

So my question goes here. Now if my Server has over 20 clients, it also has 20 threads and my desktop with an ryzen CPU goes to 100% at usage at 30 Threads. Now I'd like to handle a mass-amount of clients by one server, but the CPU is just getting over-used. My wise is very simple how I do it, but there must be a better way; because I saw many good java servers so far yet. I don't know what I do wrong though. In the following I share my code, how I do it in principle.
while(this.isRunning()) {
ServerSocket server = new ServerSocket(8081);
Socket s = server.accept();
new Thread(new WorkerRunnable(s)).start();
//now here if e.g. over 25 users connect there are 25 threads. CPU is at 100%. Is there a better way to handle this?
The worker runnable is identifing the clients. After that they will get into a chat-room. Its like a group chat for e.g.
Edit: Relevant parts of my very unfinished code which is still very WIP
private boolean state;
private ServerSocket socket;
#Override
public void run() {
while(this.isRunning()==true) {
try {
if(this.socket==null) this.socket = new ServerSocket(this.getPort());
Socket connection = this.socket.accept();
IntroductionSession session = new IntroductionSession(this, connection);
new Thread(session).start();
//register timeout task for 3 secs and handle it async
System.out.println(ManagementFactory.getThreadMXBean().getThreadCount());
//this.handleIncomingConnection(connection);
} catch(Exception e) {
e.printStackTrace();
//System.exit(1);
}
}
}
private class IntroductionSession implements Runnable {
private boolean alive = true;
private BaseServer server;
private Socket socket;
private boolean introduced = false;
public IntroductionSession(BaseServer server, Socket socket) {
this.server = server;
this.socket = socket;
}
private void interrupt() {
System.out.println("Not mroe alive");
this.alive = false;
}
private void killConnection() {
this.killConnection("no_reason");
}
private void killConnection(String reason) {
try {
if(this.from_client!=null) this.from_client.close();
if(this.to_client!=null) this.to_client.close();
this.socket.close();
switch(reason) {
case "didnt_introduce":
System.out.println("Kicked connection, cause it didn't introduce itself");
break;
case "unknown_type":
System.out.println("Kicked unknown connection-type.");
break;
case "no_reason":
default:
//ignore
break;
}
} catch (IOException e) {
switch(reason) {
case "didnt_introduce":
System.out.println("Error at kicking connection, which didn't introduce itself");
break;
case "unknown_type":
System.out.println("Error at kicking unknown connection-type.");
break;
case "no_reason":
default:
System.out.println("Error occured at kicking connection");
break;
}
e.printStackTrace();
}
}
private ObjectInputStream from_client;
private ObjectOutputStream to_client;
#Override
public void run() {
while(this.alive==true) {
try {
if(this.to_client==null) {
this.to_client = new ObjectOutputStream(this.socket.getOutputStream());
//this.to_client.flush();
}
if(this.from_client==null) this.from_client = new ObjectInputStream(this.socket.getInputStream());
//Time runs now, if socket is inactive its getting kicked
new Timer().schedule(new java.util.TimerTask() {
#Override
public void run() {
if(IntroductionSession.this.introduced==false) {
IntroductionSession.this.killConnection("didnt_introduce");
Thread.currentThread().interrupt();
IntroductionSession.this.interrupt();
}
}
}, 5000
);
Object obj = this.from_client.readObject();
while(obj!=null) {
if(obj instanceof IntroductionPacket) {
IntroductionPacket pk = (IntroductionPacket) obj;
introduced = true;
if(isCompatible(pk)==false) {
try {
this.to_client.writeObject(new DifferentVersionKickPacket(BaseServer.version));
this.to_client.close();
this.from_client.close();
IntroductionSession.this.socket.close();
System.out.println("Kicked socket, which uses another version.");
} catch(Exception e) {
Thread.currentThread().interrupt();
//ignore
System.out.println("Error at kicking incompatible socket.");
e.printStackTrace();
}
} else {
this.server.handleIncomingConnection(this.socket, this.from_client, this.to_client);
}
Thread.currentThread().interrupt();
}
}
} catch(StreamCorruptedException e) {
//unknown client-type = kick
this.killConnection("unknown_type");
} catch (IOException|ClassNotFoundException e) {
e.printStackTrace();
this.killConnection("no_reason");
}/* catch(SocketException e) {
}*/
}
Thread.currentThread().interrupt();
}
}
Extending class, which is an actual server:
#Override
public void handleIncomingConnection(Socket connection, ObjectInputStream from_client, ObjectOutputStream to_client) {
new AuthenticationSession(connection, from_client, to_client).run();
}
private class AuthenticationSession implements Runnable {
private Socket socket;
private ObjectInputStream from_client;
private ObjectOutputStream to_client;
public AuthenticationSession(Socket socket, ObjectInputStream from_client, ObjectOutputStream to_client) {
this.socket = socket;
this.to_client = to_client;
this.from_client = from_client;
}
//TODO: Implement app id for access tokens
#Override
public void run() {
try {
while(this.socket.isConnected()==true) {
/*ObjectOutputStream to_client = new ObjectOutputStream(socket.getOutputStream()); //maybe cause problems, do it later if it does
ObjectInputStream from_client = new ObjectInputStream(socket.getInputStream());*/
Object object = from_client.readObject();
while(object!=null) {
if(object instanceof RegisterPacket) {
RegisterPacket regPacket = (RegisterPacket) object;
System.out.println("Username:" + regPacket + ", password: " + regPacket.password + ", APP-ID: " + regPacket.appId);
} else {
System.out.println("IP " + this.socket.getInetAddress().getHostAddress() + ":" + this.socket.getPort() + " tried to send an unknown packet.");
this.socket.close();
}
}
}
}/* catch(EOFException eofe) {
//unexpected disconnect
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
catch(Exception e) {
e.printStackTrace();
System.exit(1);
}
/*catch(Exception e) {
//e.printStackTrace();
Thread.currentThread().interrupt();
}*/
}
}
Please dont look at its very bad formatting and stuff I did in hope to fix it, the tasks dont die whyever though.

Generally, in production grade server code, we don't work with direct creation of socket and handling of requests. It's a nightmare to work with low level sockets, close connections and prevent leaks. Rather, we rely on production grade frameworks such as Java Spring Framework or Play Framework.
My question is, why aren't you using any server-side frameworks such as the ones I listed above?
If you're wondering how these frameworks handle thousands of concurrent requests, look into design patterns such as Thread Pool. These frameworks abstract away the complexities and handle the thread pool for you.
If the clients aren't expected to receive an immediate response, you could also look into introducing messaging queue such as Kafka. The server will pick the messages one by one from the queue and process them. However, bear in mind that this is asynchronous and may not meet your requirements.
If you're not just restricted to one server, you could look into deploying your server code to Azure or AWS VMSS (Virtual machine scale set). Based on CPU load rules you configure, the system will autoscale and dynamically manage resources for you.
I would suggest reading upon system design principles related to servers to reinforce your understanding.
Don't reinvent the wheel.

Since you are doing a Chat Application you need to think of doing a Single Threaded Event Loop.
You can Keep a Map of String (Client id) and Socket (Client socket).
Map<String, Socket> clientSockets;
You Server thread will accept new Client Sockets and will just put it in the above map. Then there will be another Thread which will do the Event Loop and whenever there is data in any of the Client Socket in InputStream it should send that data to all other Client Sockets (Group Chat). This should happen infinitely with a Sleep interval.

Related

JAVA SOCKET realize disconnect after two writes

an app in PC using JAVA io.socket which will sends json to a server device ESP8266on TCP on LAN network
when you are connected and when disconnect sequence is executed from java it self everything is ok .
java is client and device is server , when device cuts the connection (here lets use Hercules on localhost) the java program will not being noticed and when i try to write with outputstreamwriter it dose not trig an exception , exception will be executed after at least two writes to socket after the server is being disconnected and the last two writes which was not being received by server will return success! in java. i have read other programmers use a byte send to see if connection is still alive . the same problem is there too . if i send two write each 20 seconds time in between its going to be 60 seconds before java realize server is disconnected and if i send every 1 second is going to be a lot of ATcommand interrupts for nothing .
here is my code:
public boolean Write(String data){
System.out.println("StartSending");
if(TESocket.Connected)
{
Thread write = new Thread(new Runnable() {
#Override
public void run() {
try
{
outputStreamWriter.write(data);
outputStreamWriter.flush();
}
catch (IOException e)
{
TESocket.Connected=false;
System.out.println("Faild");
System.out.println(e.getCause());
}
}
});
write.start();
return true;
}
else
{
System.out.println("Not Connected");
return false;
}
}
The TESocket is class which handles Socket using Runnable and Connected is a static boolean since there is just one socket at a time here is the connect method
public boolean Connect(){
Thread connect = new Thread(new Runnable() {
#Override
public void run() {
try {
socket= new Socket("127.0.0.1",Integer.parseInt(port));
if(socket.isConnected())
{
inputStreamReader = new InputStreamReader(socket.getInputStream());
outputStreamWriter = new OutputStreamWriter(socket.getOutputStream());
TESocket.Connected=true;
System.out.println("Connected");
}
} catch (IOException e) {
System.out.println("Faild to Connect");
e.printStackTrace();
}
}
});
connect.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(TESocket.Connected)
return true;
else
return false;
}
how can i be noticed if server is out of reach with immediately after sending the write? or is there eny event for noticing that ? maybe some king of asynchronous socket? like it was in QT (Signal Slot for Disconnect)
well By reading method and setting a timeout solved this problem , thanks to reading some post
in read if i am still connected and not receiving any data time out will be thrown which bring me back to the first lie of the while loop
if i receive data i will be bigger than zero which reader will read data and flag the rec=true so the disconnect sequence dose not take in place
if i don't receive any data and timeout dose not occurs the rec=false and exception will not be thrown so the program will o to disconnect routine
setting the timeout to 1 millisecond makes it real-time (proportional to my work) in deadline detection
public boolean Read()
{
if (TESocket.Connected)
{
try {
socket.setSoTimeout(1000);
} catch (SocketException e) {
System.out.println("Problem Timeout");
e.printStackTrace();
}
Thread read = new Thread(new Runnable() {
#Override
public void run() {
int i;
boolean rec=false;
while (true)
{
char[] reader = new char[250];
try {
//while(!inputStreamReader.ready());
i=inputStreamReader.read(reader);
if(i>0) {
System.out.println(reader);
rec=true;
}
// Thread.sleep(2500);
if(!rec)
{
System.out.println("Disconnected");
TESocket.Connected=false;
inputStreamReader.close();
outputStreamWriter.close();
socket.close();
break;
}
rec=false;
}
catch (IOException e)
{
System.out.println("Connected");
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
read.start();
}
return true;
}

Server hangs when client disconnects

i am creating a multiple-client/server app whenever any client disconnects from
my server it just hangs.
how can i set any condition that will tell me print some message whenever
any client disconnects from the server
here is my server code
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
System.out.println("server starting.......");
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.println("Ready to accept.......");
socket = serverSocket.accept();
System.out.println(" client Connected with ip address =" +socket.getRemoteSocketAddress().toString());
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
System.out.println("catch block");
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
any help will be appreciated
It's not clear whether you mean disconnect because the conversation was over (ie: everything completed successfully) or the disconnect is because of some network problems (or the client canceled the request).
If it's the first case, then it's easy: the protocol you are using (your own, or http, or whatever) is in charge of defining how to determine that a conversation was over. If that situation arises, then you just close the socket.
If it's the second case, then you'd have to have an algorithm in place to determine whether or not the connection must be closed. For instance, by implementing a timeout, or a slow-read threshold. Take a look at the Socket's javadoc for instructions on how to set a timeout.
It's also worth noting that it's fine to create your own servers when you want to practice or learn something, but you'd be better off using an existing solution, like vert.x or a slimmed down version of Wildfly, for instance. The overhead of such servers is very low, nowadays, while still providing very robust networking capabilities.

Android AsyncTask stuck

Context:
The following AsyncTask for an android application sends and receives so called Request objects from a server.
If the user makes changes to his stuff in the app, new request objects get generated and added to the synchronization queue. If he then hits the sync-button the AsyncTask is created and executed with his requests as parameters.
The handler finally takes all answers and sets the neccessary consequences in the database. He then finally updates the UI by calling one single method on the UI thread (onPostExecute).
public class RequestSender extends AsyncTask<Request, Void, Boolean>{
// Server data
private String host;
private int port = 1337;
private Socket socket;
private AnswerHandler handler;
public RequestSender(AnswerHandler handler) {
this.host = "hostNameHere";
this.handler = handler;
}
/**
* This method gets started as asynchronous task when you call .run()
* #return
*/
#Override
protected Boolean doInBackground(Request... requests) {
return sendAndReceive(requests);
}
private boolean sendAndReceive(Request... requests) {
boolean isConnected = this.initSocket();
if(isConnected) {
this.send(requests);
this.waitForAnswer();
} else {
handler.setRequests(requests);
}
return isConnected;
}
/**
* Tries to open a socket on the android device to a specified Host
*/
private boolean initSocket() {
try {
SocketAddress sockaddr = new InetSocketAddress(host, port);
socket = new Socket();
socket.connect(sockaddr, 5000);
return true;
} catch (UnknownHostException e) {
System.err.println("Unknown Host in initSocket()");
} catch (IOException e) {
System.err.println("Connection timed out");
}
return false;
}
/**
* Tries to send a request to the server
* #param request
*/
public void send(Request... request) {
if(socket != null) {
try {
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
out.writeObject(request);
out.flush();
} catch (IOException e) {
System.err.println("Couldn't write to socket in RequestSender");
}
}
}
/**
* Waits for the answer from the server and reports the result in the handler
*/
private void waitForAnswer() {
try {
socket.setSoTimeout(5000);
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
Request[] answers = (Request[]) in.readObject();
socket.close();
handler.setRequests(answers);
} catch (StreamCorruptedException e) {
System.err.println("Failed to open stream from server");
} catch (IOException e) {
System.err.println("Failed to read answers from server");
} catch (ClassNotFoundException e) {
System.err.println("Failed to read class from server");
}
}
#Override
protected void onPostExecute(Boolean a) {
handler.updateUI();
}
}
Now my Problem:
The whole thing works without any problem for a few times (It depends on the goodwill of my phone how many times), but then it seems like the task gets stuck somewhere without giving me any error message on System.err.
Restarting the app solves the problem and it works again without any problem.
I already read that AsyncTasks get executed on one single thread since Honeycomb. I set a timeout on open socket and read in, so a stuck task should terminate after this timeout.
Is there any problem with my code and could you imagine a solution for this?
Recently I face this problem and after debugging a lot and brain storming for a week I finally got the bug.
Ok lets do some homework.
Process to send/receive data
Establish a connection. Let assume connectToServer() is a function that physically connects the device to the server.
The socket/TCP part. In your case you have doInbackground(), in which you are calling initSocket() to initiate a socket connetion.
In real world scenario when you request a connection to a server it takes some time, may be a one or two seconds. So you should wait for that time before initiating a socket connection request. If a socket request send before a connection then it goes to lock state and releases after the default time out is finished which make it stuck.
Programming scenario
connectToServer();
// wait for 1 or 2 second.
initSocket();
Sample code
/* Function to check whether we are physically connected to the server or not */
private boolean isConnEstablished(){
WifiInfo connInfo = mManager.getConnectionInfo();
return mManager.isWifiEnabled() && connInfo.getNetworkId() != -1 && connInfo.getIpAddress() != 0;
}
private void initSocket() {
boolean scanning = true;
int tryCount = 5; // we trying for 5 times
try {
while (scanning && tryCount > 0) {
try {
if (isConnEstablished()) {
try{
Thread.sleep(500);
}catch (InterruptedException e){
Log.e("Yo", "sleep-error");
}
tConnection = new Socket(host, port);
scanning = false;
Log.e(getClass().getName(), "Socket connection established");
}else {
throw new ConnectException();
}
} catch (ConnectException e) {
Log.e(getClass().getName(), "connecting again...");
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Log.e(getClass().getName(), "System sleep-error: " + ex.getMessage());
}
}
tryCount--;
}
}

server handling many clients java

guys! i wrote simple server client (udp) application. Now i am trying to make server that accepts many clients. As, i understood, i need to create functions, that accepts and handle clients, but i am confused about apps structure. Can u check if i have right skeleton for my app? Mayb u can give me some hint or example. All advice appreciated! :)
class MultiServer {
private DatagramSocket serversocket;
public MultiServer() {
try {
this.serversocket = new DatagramSocket(6789);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() throws IOException {
while(true) {
DatagramSocket serversock = serversocket.accept();
new Thread(new ClientHandler(serversock)).start();
}
}
public static void main(String[] args) {
Server1 server = new Server1();
try {
server.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ClientHandler implements Runnable {
private final DatagramSocket clientsocket;
ClientHandler(DatagramSocket sock) {
this.clientsocket = sock;
}
#Override
public void run() {
//receive packet, send msg, get ip, get portnumber ?
}
}
}
So you want your server to be able to operate with multiple requests at the same time? Good, it's how most web-servers work. You have to understand the basic concepts of multi-threading and concurrency.
A simple server can only handle ONE thing at a time. What happens if another request is received while the server is dealing with something else? Nothing, so the application isn't very efficient and not scalable at all.
If you haven't used multiple threads in your applications yet and don't know much about concurrency, it's a great time to have a go, read the Oracle Concurrency Lesson, or find a tutorial online, there are plenty.
Now, once (or if) you know how threading works make sure you break down your functions as much as possible and see what functions can happen at the same time. An example of a Web Server that i can think of is this:
A separate thread to listen on the port for requests. Once a request is received, place it in the 'request pool' and queue it to be processed
A separate thread (or multiple threads/thread pool) that process the request
Your structure looks like you have both receive and process in the same Runnable. Anyway, this is just an idea, you'll have to see what's more applicable to your application. Also, have a look at the Concurrency tools that newer Java versions provide, Java 6 and 7 provide a lot of tools you can use that are very effective (but also quite hard to understand and use in my opinion).
Good luck!
You are looking for a Threadpooled Server. The way you started is good. Now you simply implement a Java execution Service to Handle the requests. The threadpool has a fixed of thread. It does take your requests and put those in a queue and if a request is done it takes the next request. So you normaly dont lose any requests.
Here is a small example i made:
public class PoolServer implements Runnable {
private static final int DEFAULT_PORT = 8080;
private static final String CONFIG = "config.xml";
protected ServerSocket serverSocket = null;
protected boolean isStopped = false;
protected Thread runningThread = null;
protected ExecutorService threadPool = Executors.newFixedThreadPool(100);
protected int serverPort;
public PoolServer() {
// getting the port from the XML
this.serverPort = getPortFromXML();
}
public void run() {
synchronized (this) {
this.runningThread = Thread.currentThread();
}
openServerSocket();
// accepting loop
while (!isStopped()) {
Socket clientSocket = null;
try {
// accept the client
clientSocket = this.serverSocket.accept();
clientSocket.setSoTimeout(2000);
} catch (IOException e) {
if (isStopped()) {
return;
}
throw new RuntimeException("Error accepting client connection",
e);
}
this.threadPool.execute(new ThreadHandler(clientSocket));
}
// loop end
// server stopped shut down the ThreadPool
this.threadPool.shutdown();
}
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);
}
}
private void openServerSocket() {
try {
this.serverSocket = new ServerSocket(this.serverPort);
} catch (IOException e) {
throw new RuntimeException("Cannot open port " + this.serverPort, e);
}
}
At this point this.threadPool.execute(new ThreadHandler(clientSocket)); i do execute the request if a thread is free. Else it get into the queue of the Threadpool.
You can even change it from a Fixed to some other Threadpools! Just take a look at the Executors and take what you need. Executors
Hope this helps!

Java Server socket stuck on accept call (Android Client, Java Server)

Below I have put a fragment of code to help understand my problem. I have a server code, works fine for the first time the client loads and sends a packet. After the first packet is received, the server is stuck on "accept".
I have wireshark configured for this port, and the server is getting those packets. I just wonder why accept wont return more than once. Its driving me nuts.
Server Code
public class DAPool implements Runnable {
private ServerSocket serverSocket;
private ArrayList<DA> pool;
private LinkedList<Socket> clientConnQ;
public DAPool(int newPoolSize, int serverPort) {
try {
serverSocket = new ServerSocket(serverPort, 500, InetAddress.getByName("127.0.0.1"));
} catch (IOException e) {
e.printStackTrace();
return;
}
poolSize = newPoolSize;
clientConnQ = new LinkedList<Socket>();
pool = new ArrayList<DA>(poolSize);
DA deviceThread;
for (int threads = 0; threads < poolSize; threads++) {
deviceThread = new DA();
connPool.add(deviceThread);
deviceThread.start();
}
}
public void run() {
while (true) {
Socket incomingSocket;
try {
incomingSocket = serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
return;
}
insertNewConnToQ(incomingSocket);
}
}
private class DA extends Thread {
private Socket clientSocket;
private ObjectInputStream inputObjectStream;
public DA() {
}
public void run() {
while (true) {
while (clientConnQ.isEmpty()) {
synchronized (clientConnQ) {
try {
clientConnQ.wait();
} catch (InterruptedException ignored) {
ignored.printStackTrace();
}
}
}
synchronized (clientConnQ) {
clientSocket = (Socket) clientConnQ.removeFirst();
try {
inputObjectStream = new ObjectInputStream(clientSocket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
return;
}
// Do something useful here
}
}
}
}
}
Client Code
public class SendQueue extends Thread {
LinkedList<Message> requestQ;
Message sendRequest, requestMessage;
Socket clientSocket;
OutputStream outputStream;
ObjectOutputStream objectOutputStream;
public SendQueue(Socket newClientSocket) {
requestQ = new LinkedList<Message>();
clientSocket = newClientSocket;
}
public void run() {
while (true) {
synchronized (requestQ) {
while (requestQ.isEmpty()) {
try {
requestQ.wait();
} catch (InterruptedException ignored) {
ignored.printStackTrace();
}
}
sendRequest = requestQ.removeFirst();
}
try {
outputStream = clientSocket.getOutputStream();
objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(sendRequest);
objectOutputStream.flush();
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
} catch (RuntimeException e) {
e.printStackTrace();
}
}
}
public int sendRequest(Message message) {
synchronized (requestQ) {
requestQ.addLast(message);
requestQ.notify();
}
return 0;
}
}
I don't see a timeout being set on the serverSocket.
ServerSocket.accept() is a blocking operation so it will block until either an error occurs, a timeout occurs, or a connection is accepted.
Try
SererSocket.setSOTimeout(10000)
You also don't seem to be closing your streams when your finished.
Are you sure that it is sticking on the accept call? Did you get a stacktrace that shows it waiting on accept?
Assuming it is getting stuck elsewhere I'm wondering if it isn't because clientConnQ is being held in one of your DA instances. The synchronized block covers the // Do something useful here section.
I wonder if it might work if you changed the code to be
synchronized (clientConnQ) {
clientSocket = (Socket) clientConnQ.removeFirst();
}
try {
...
Once you have your clientSocket from clientConnQ then no other instance can process that socket.
Ok, if I got a $ for everytime I asked a silly question :)
Here goes. A client socket connects and thats when a server receives a accept call. For some silly reason I was waiting on accept for receiving further data from the client. Infact, I should just wait for something on the "stream" and then process the stream. I should not wait on the accept for that connection.
Accept is to be called to "connect" to the socket, not to receive data continuously.
Thanks for your all your help. You forced me to think about thread synchronization, the design, sockets in general and finally arrive that the solution.
Fantastic responses people. Thanks.
Siddharth

Categories