Why is this message getting sent to the wrong client? (Deduping) - java

I have a chat program. The problem is that I am trying to disallow dupe names. Essentially, whenever a name change request is sent to the server, it is checked against the list of names currently in use and if it is already taken, the person is added to my shitlist (not allowed to post) and they are sent a message that they need to change their name.
I commented the crap out of the code since there is a lot so you can understand it easily.
The problem is that the wrong person is being sent the message that the name is already in use! I have spent the last 8 hours trying to find it and It's bloody driving me mad!
The server side code is long; I'll post the relevant bits and any further will be provided on request. I'll also link to the complete program. (Not the source, the JAR.)
JAR: https://www.mediafire.com/?4t2shjdjf7blpg2
//...Irrelevant bits ommitted...//
public class Server
{
// The server object reference
static Server server;
// Declarations:
private ArrayList<ObjectOutputStream> clientOutputStreams; // out streams
private ArrayList<String> takenNames = new ArrayList<>(); // taken names
private InetAddress ip;
private final int serverPort; // the port the server is running on
private static ObjectOutputStream changer; // the last person to change names
private ArrayList<ObjectOutputStream> shitList = new ArrayList<>();
private HashMap <InetAddress, ObjectOutputStream> ipMap =
new HashMap<>(); // <ip, outputstream>
//...Irrelevant bits ommited...//
// Don't mind this non-indentation, it is supposed to be.
public void tellEveryone(Message message, InetAddress senderIP)
{
// First check some special conditions..
if(message.getType() == Message.TYPE.IN_USE)
{
try
{
changer.writeObject(message);
}
catch (IOException e)
{
e.printStackTrace();
}
}
// If someone is on my shitlist,
if(shitList.contains(ipMap.get(senderIP)))
{
// Warn them of their sins...
Message nopeMessage = new Message(Message.TYPE.SERVER,
"You may not send any messages until you change your name!",
"Server");
try
{
ipMap.get(senderIP).writeObject(nopeMessage);
}
catch(IOException e)
{
e.printStackTrace();
}
}
else
{
// Send message normally to everyone...
// Sync, just to be safe
synchronized(clientOutputStreams)
{
for(ObjectOutputStream oo : clientOutputStreams) // while more clients...
{
try
{
oo.writeObject(message);
oo.flush();
}
catch(IOException e)
{
System.out.println("IOException caught during tellEveryone()");
e.printStackTrace();
}
}
}
System.out.println(getTimeStamp() + ": Message Sent by:".
concat(" " + senderIP + "/ " + message.getSenderName()));
}
}
The server handler inner class...
public class ServerHandler implements Runnable
{
#Override
public void run()
{
// Create a list of client out streams to send stuff...
clientOutputStreams = new ArrayList<>();
try // To establish a connection with clients
{
// Create server socket...
ServerSocket serverSocket = new ServerSocket(serverPort);
while(true) // Will always run! Blocks!
{
// Assign a client socket to any new socket connections...
// (The var used here is temp, but will be passed off soon.)
Socket clientSocket = serverSocket.accept();
// Get's the ip of the client that connected...
ip = clientSocket.getInetAddress();
System.out.println(ip + " " + "connected.");
// Create ooStream to send messages to client...
ObjectOutputStream ooStream =
new ObjectOutputStream(
clientSocket.getOutputStream());
// Add the client oo stream to the list of outputs...
clientOutputStreams.add(ooStream);
// Add user IP data to map of ip's
ipMap.putIfAbsent(ip, ooStream);
// Create new thread to run inner class ClientHandler...
Thread t = new Thread(new ClientHandler(clientSocket));
// Running the thread makes it safe to overwrite the...
// ...clientsocket variable.
t.start();
}
}
catch (IOException e)
{
System.out.println("Exception in server.run()");
// TODO: Revise
e.printStackTrace();
}
}
}
The client handler inner class
public class ClientHandler implements Runnable
{
private ObjectInputStream oInStream; // The client's input stream.
private Socket socket; // Socket to the client
public ClientHandler(Socket clientSocket)
{
try // to create an input stream...
{
socket = clientSocket; // <-- The one passed in to the method
// Potential error from previous version... REMOVE WHEN TESTED
oInStream = new ObjectInputStream(socket.getInputStream());
}
catch(IOException e)
{
System.out.println("Error establishing input stream");
}
}
#Override
public void run()
{
Message message;
try // To process incoming messages...
{
while(socket.isClosed() == false) // If the socket is open...
{
// While there are more messages...
// Also assigns to the message var.
while((message = (Message)oInStream.readObject()) != null)
{
// Passes on the message and sender info.
if(message.getType() == Message.TYPE.NAME_REQUEST)
{
changer = ipMap.get(socket.getInetAddress());
System.out.println(socket.getInetAddress());
System.out.println(changer.toString());
handleNameRequests(message);
}
else
{
tellEveryone(message, ip); // TEST CHANGE- DELETED IF TEST
}
}
// TEST TEST TEST
synchronized(clientOutputStreams)
{
int index =
clientOutputStreams.indexOf(
socket.getOutputStream());
clientOutputStreams.remove(index);
System.out.println("Removed the client in sync");
}
}
// TEST TEST TEST
socket.close(); // TEST CLOSING SOCKET WHEN DONE.
System.out.println("Sock closed after while loop in ch run()");
}
catch(IOException e)
{
System.out.println("IOException caught when "
+ "reading message.");
}
catch (ClassNotFoundException e)
{
System.out.println("Some poor sap is going to have to debug"
+ "this!");
}
finally
{
// THIS WHOLE BLOCK: TEST TEST TEST
try
{
oInStream.close();
System.out.println("just closed oinStream");
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
}

I FINALLY FOUND IT!
For any future people encountering a similar problem, the problem was that I was assigning the ip variable in the wrong place! This essentially resulted in the list of ip's being all the same! Another bug confounded that problem, in that when I disabled the sending ability of messages when on my shitlist (aren't programmers the darndest?), I disabled ALL types of messages, including those from the server, ect! Oops!
The lesson? Bugs hide in the darndest places. Walk through everything, and doubt what you know to be true. Assume nothing, verify everything. There are never enough print statements when debugging!

Related

Bi-direction multithreaded socket connection

The situation is as following:
There is a server and a client, which both can initiate a command/message to each other.
Because the server can send a message at any time, the listening on the socket is done in a separate thread (a ListenerThread). This is all fine. The client can send messages and receive at the same time, however, how would you know if a certain response belongs to the command you sent when the server can also initiate a new command/message to notify that something happened?
If I send a message to the server, and the server responds with "OK" in the listening thread. How would you know this is the actual response of the message/command you sent (keeping in mind this is another thread). What if the server received an update from another client and sends that update first.
This like a chat application, though with an actual response for every sent command.
example case:
Let us say that the protocol only consists of a move <playernum> [<x>,<y>] command which indicates that a player has done a move (server notifies client) or that a player wants to do a move (client notifies server). Also, the server responds with "OK" if the move was okay or with "ERR" if not.
Safe state:
move 1 [3,4]
client ---> server
OK
client <--- server
Unsafe state:
move 1 [3,4]
client ---> server
move 2 [1,2]
client <--- server
OK
client <--- server
The client did not expect this response... should responded with OK.
You have a protocol where the client can read one of three possible messages:
OK (The move you made was accepted)
ERR (The move you made was rejected)
move PLAYERID <co-ord1,co-ord2>
It is a reasonable assumption that the messages OK and ERR will only be sent back to the socket which requested a move. However a legal move is broadcast to all other players (perhaps excluding the player who moved).
Since you can receive unsolicited responses (the moves that other players make), you have correctly created a listener thread. You have not described the action your application takes when it receives a move message from another client, but I will assume that your listener thread handles that case. What remains is how to co-ordinate your move commands, and the response to that which will appear in the listener thread.
To synchronize the submission of your move command, and the response, a BlockingQueue (called queue) will be used , and shared between the client and listener. The form of this will be:
Client:
out.println(command); // Where out is the socket PrintWriter stream
String response = queue.take(); // Where queue is the BlockingQueue
// Process either `OK` or `ERR`
Listener Thread:
while ((command = in.readLine()) != null) {
if (command.equalsIgnoreCase("OK") || command.equalsIgnoreCase("ERR"))
queue.put(command);
else if (command.startsWith("move")) {
// Process a move
}
else
System.out.println("Unrecognized command="+command);
}
As you can see, the client simply submits a command, and blocks for the response of "OK" or "ERR". The requirement for processing other player moves has moved into the listener thread.
The listener processes all three conditions (Another player move, an "OK" or an "ERR"). The messages responses "OK" and "ERR" are sent back to the client. A move command is processed separately, and as such is not the responsibility of the client making the moves.
Below I have mocked working code which demonstrates these concepts. The server will randomly (with equal probability) respond with:
OK
ERR
A multiline response which includes OK and another player's move
Code:
public class MoveGame {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String command = "";
new Thread(new MoveServer()).start();
Socket socket = null;
PrintWriter out = null;
BlockingQueue<String> queue = new ArrayBlockingQueue<String>(10);
try {
socket = new Socket("localhost", 5001);
out = new PrintWriter(socket.getOutputStream(), true);
new Thread(new ClientReader(socket, queue)).start();
while (!command.equals("quit")) {
command = scanner.nextLine();
if (command.startsWith("move")) {
out.println(command);
String response = queue.take();
System.out.println("Client got response="+response);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
scanner.close();
out.close();
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
static class ClientReader implements Runnable {
private final Socket socket;
private final BlockingQueue<String> queue;
public ClientReader(Socket socket, BlockingQueue<String> queue) {
super();
this.socket = socket;
this.queue = queue;
}
#Override
public void run() {
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String command;
while ((command = in.readLine()) != null) {
if (command.equalsIgnoreCase("OK") || command.equalsIgnoreCase("ERR"))
queue.put(command);
else if (command.startsWith("move")) {
System.out.println("A player made a move: command="+command);
}
else
System.out.println("Unrecognized command="+command);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
static class MoveServer implements Runnable {
#Override
public void run() {
Random random = new Random();
Socket socket = null;
try {
ServerSocket ss = new ServerSocket(5001);
while (true) {
System.out.println("Listening for new connections");
socket = ss.accept();
System.out.println("New session has started");
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String command;
while ((command = in.readLine()) != null) {
System.out.println("Got command="+command);
int responseType = random.nextInt(3);
if (responseType == 0)
out.println("OK");
else if (responseType == 1)
out.println("ERR");
else {
out.println("move 1 [3,4]");
out.println("OK");
}
}
in.close();
out.close();
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

simple multi-threaded server chat using java

I'm creating a java chat server that handles multi clients I use this simple code for server
public class Server extends Thread {
ServerSocket serverSocket = null;
Socket socket = null;
private int unique_id;
ArrayList<Clients> cl;
public Server(int port) {
try {
serverSocket = new ServerSocket(port);
cl = new ArrayList<>();
this.start();
} catch (Exception e){
System.out.println("Error 5");
e.printStackTrace();
}
}
#Override
public void run(){
System.out.println("Server Start");
while (true){
try {
socket = serverSocket.accept();
Clients t = new Clients(socket); // add it to thread
cl.add(t);
t.start();
System.out.println("Connected " + String.valueOf(cl.size())); // printed ok
}catch (Exception e){
System.out.println("Error 4");
e.printStackTrace();
}
}
}
public synchronized void SendToAll(String s){ // this function used by client when one of client socket send a message then server send it to all
System.out.println("Sended is excuted"); // excuted normal each time i send a message from client but not send to all
for (int i = 0; i < cl.size(); i++){
cl.get(i).WriteToSocket(s);
}
}
public static void main(String args[]){
int port = 5002;
Server server = new Server(port); // start server
//server.run(); // start connections wait for it
}
class Clients extends Thread { // class extends thread
public Socket socket = null;
DataInputStream input = null; // read input
DataOutputStream output = null; // read output
public int myid = 0; // unique id for each client
public Clients(Socket soc) {
socket = soc;
try {
input = new DataInputStream(socket.getInputStream());
output = new DataOutputStream(socket.getOutputStream());
myid = ++unique_id;
System.out.println("Client Start Thread"); // printed ok !
} catch (IOException e){
System.out.println("Error 1");
e.printStackTrace();
}
}
public void WriteToSocket(String s) { // used to write a message to this socket
try {
output.write(s.getBytes());
}catch (IOException e){
System.out.println("Error 2");
e.printStackTrace();
}
}
#Override
public void run() { // run thread function wait for messages from clients
while (true){
try {
String s = input.readLine();
if (s.contains("quite")) {
socket.close();
input.close();
output.close();
cl.remove(this);
this.stop();
}
if (!s.isEmpty()) {
SendToAll(s);// when message come and not empty it use server function to send them to all clients
}
}catch (IOException e){
System.out.println("Error 3");
e.printStackTrace();
}
}
}
}
}
everything works fine when clients connect the server accept the connection and the client thread started
but the problem when I sent a message from the client it didn't received by the server I try my client application in java too with Qt c++ server and it works ?
so what did I do wrong here make the server can't receive the message ?
this my first time in network programming using java
Edit
I solve the NullPointerException the problem was that when client log out I didn't remove his socket from the ArrayList solved by making client before close send message contains quite so when I see it i remove his socket from array list Another Quetiosn Here i don't know how this message sentthe System.out.println() that is in the SendToAll function printed to the screen each time client send a message but why the message not send again to all clients ? actually the main problem is that server can't send the message to all clients in the array list after message comes from one client the problem not solved stell found
Client Code class
public class ClientSocket extends Thread {
public Socket socket = null;
public DataInputStream input = null;
public DataOutputStream output = null;
MainChat chat = null;
public ClientSocket(String ip, int port,MainChat ch) {
try {
socket = new Socket(ip,port);
input = new DataInputStream(socket.getInputStream());
output = new DataOutputStream(socket.getOutputStream());
chat = ch;
this.start();
}catch (IOException e){
}
}
#Override
public void run() {
while (true){
try {
String s = input.readLine();
if (!s.isEmpty()){
chat.WriteToScreen(s.trim());
}
}catch (IOException e){
}
}
}
public void WriteToSocket(String s) throws IOException{
output.write(s.getBytes());
}
}
Edit
when i use this code in main the SendToAll function send the message to all clients !! why when i use it from clients class using Thread it not sended to all ?
public static void main(String args[]){
int port = 5002;
Server server = new Server(port); // start server
//server.run(); // start connections wait for it
while (true) {
String s = in.next();
server.SendToAll(s + "\n"); // message sended to all client !!
}
}
The problem is that readLine reads until it finds a line terminator of end of file. This is why it works with other server in QT C++ but not with the Java server.
Please see here:
https://docs.oracle.com/javase/7/docs/api/java/io/DataInput.html#readLine()
https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#readLine()
Please note that readLine in DataInputStream is deprecated. You should use BufferedReader to read a line (with readLine) as indicated in the DataInputStream link.
So, add '\n' to the end of the string sent and it will work.
I solve the problem, I am sorry for that it was my fault I forget to add \n in sendToAll function so this what cause the problem so no \n the clients can't read the line because I use readLine in DataInputStream
anyway I try another method to read bytes instead of readLine it's I think it's better especially when you receive UTF-8 char and after that changes from bytes to String

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--;
}
}

Object stream I/O issue, client object not updated

i'm working a client-server based game. The game is mainly caracterized by a Grid object which must be synchronized between clients. To do that I use the Object I/O Streams over Sockets.
However i encounter an issue during the synchronization process. The Grid is sent and recieved by all clients but its state is not modified after the first upload to each client.
I mean by that that clients do recieve the object in its present state when they connect but subsequent receiptions (initiated by either another client connection or previous client moves) don't present any modification over the initial sent state...
here are (stripped-down) snippets of the server side code:
while(true) //continuously accept new connections
{
//wait incoming connection, and accept it
Socket newSocket = serverListener.accept();
//create player details and save it in hashtable
Player newPlayer = new Player(newSocket); //streams saved here
Players.put(newPlayer);
//update all clients
sendGridToAll();
}
The Player class constructor:
public Player(Socket s) throws IOException
{
this.Tx = new ObjectOutputStream(socket.getOutputStream());
this.Rx = new DataInputStream(socket.getInputStream());
}
The SendToAll method:
public void sendGridToAll()
{
synchronized(Players) //do nothing while players HT is being modified
{
for(Enumeration e = Players.elements(); e.hasMoreElements(); )
{
Player tmpPlayer = (Player)e.nextElement();
ObjectOutputStream tmpTx = tmpPlayer.getTx();
try {
tmpTx.writeObject(grid);
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
print.log("Grid update sent");
}
}
and here is the client side snippet handling the object reception (ran in a thread):
public void run()
{
ObjectInputStream RX = new ObjectInputStream(socket.getInputStream());
while(true)
{
try
{
RX_grid = (Grid)RX.readObject();
}
catch (IOException ex)
{
print.log("IO Error");
ex.printStackTrace();
}
catch (ClassNotFoundException ex)
{
print.log("Bad grid class UID");
}
finally
{
print.log("grid recieved");
c.updateGui(RX_grid);
}
}
}
Thank you for your help

ServerSocket java-server reads input only once?

I have written a java server and here is the code:
try
{
ss = new ServerSocket(8080);
while (true)
{
socket = ss.accept();
System.out.println("Acess given");
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//out = new PrintWriter(socket.getOutputStream(),true);
line = in.readLine();
System.out.println("you input is :" + in.readLine());
}
}
And an iphone application is the client and there is the code for it:
- (void)viewDidLoad {
[super viewDidLoad];
socket = [[LXSocket alloc]init];
if ([socket connect:#"10.211.55.2" port:8080]) {
NSLog(#"socket has been created");
}
else {
NSLog(#"socket couldn't be created created");
}
#try {
}#catch (NSException * e) {
NSLog(#"Unable to send data");
}
[super viewDidLoad];
}
-(IBAction)sendData{
[socket sendString:#"A\n"];
}
I am having 2 problems here: first is that the server is only reading the input once. The second is that when ever I try to output the data it doesn't output until I have called the method twice (clicked on the uibutton twice). Not sure what is happening here. What am I doing wrong?
You are creating a new reader everytime in your while loop. Instead move the code outside the while loop and block on the readLine() call.
socket = ss.accept();
in = new BufferedReader(new InputStreamReader(socket.getInputStream());
String line = "";
while ( true) {
line = in.readLine();
System.out.println("you input is :" + line);
if ( "Bye".equals(line) )
break;
}
Here is an example server side program.
Since alphazero posted the pattern, I will post a brief stripped down implementation:
This is the Server:
try {
ServerSocket ss = new ServerSocket(portNumber);
logger.info("Server successfully started on port " + portNumber);
// infinite loop that waits for connections
while (true) {
SocketThread rst = new SocketThread(ss.accept());
rst.start();
}
} catch (IOException e) {
logger.info("Error: unable to bind to port " + portNumber);
System.exit(-1);
}
The SocketThread is something like:
public class SocketThread extends Thread {
private Socket communicationSocket = null;
public SocketThread(Socket clientSocket) {
communicationSocket = clientSocket;
try {
input = new ObjectInputStream(communicationSocket.getInputStream());
} catch (IOException e) {
logger.info("Error getting communication streams to transfer data.");
try {
communicationSocket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
public void run() {
boolean listening=true;
DataObject command = null;
while (listening) {
try {
Object currentObject = input.readObject();
if (currentObject != null
&& currentObject instanceof DataObject) {
command = (DataObject) currentObject;
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
// If we got to this point is because we received a request from
// the client
// we can exit the loop
listening = false;
}
}
}
}
Note: "DataObject" is just a custom class which could be more practical since you can read the Dataobject itself from the socket without worrying about how many bytes you are reading, etc. Only condition is that DataObject is flagged as Serializable.
Hope it helps.
Tushar,
The general pattern is this (almost java but pseudo-code):
while (server-socket is accepting new connections)
{
// The server-socket's job is to listen for connection requests
// It does this typically in a loop (until you issue server-shutdown)
// on accept the server-socket returns a Socket to the newly connected client
//
socket s = server-socket.accept-connection();
// various options here:
//
// typically fire off a dedicated thread to servie this client
// but also review NIO or (home-grown) connection-map/handler patterns
// the general pattern:
// create a dedicated thread per connection accepted.
// pass Socket (s) to the handler method (a Runnable) and start it off
// and that is it.
// Here we use the general pattern and create a dedicated
// handler thread and pass of the new connections' socket reference
//
Thread handler-thread = new Thread (handler-routine-as-runnable, s);
handler-thread.start();
}

Categories