Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / December 2006

Tip: Looking for answers? Try searching our database.

Multiple Client Sockets, Single java program, connect to server socket, possible?

Thread view: 
dynaheir@hotmail.com - 08 Dec 2006 10:55 GMT
Hi all,

I have a strange problem. I started work on software expecting that it
was possible to create many client sockets in a single instance of a
java program that connect to a single server where ever that maybe.

In this case I have a thread running that determines actions, and
multiple threads are generated depending on the determined actions...
each thread requires a connection to the same server.

My issue is, when I call accept() and the server socket waits for a
connection... it only returns and services one socket per instance of
the program at a time. The client recieves no indication that accept()
didn't return a socket and proceeds to send data throught the socket
which is therefore lost.

Is it something I am doing wrong / not configuring in the socket or
server socket? Or is this not possible.

The sample code below demostrates the scenario... 2 clients are created
and begin sending text to the server... the server prints the text that
is received but only for the first client socket that connects... alll
other output is lost and only one request handler is spawed for the 2
requests.

Thanks for your help

Test code;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class socTest  extends Thread {

   public socTest() {
       start();
       synchronized(this) {
           try {
               wait(1000);
           } catch (InterruptedException ex) {
               ex.printStackTrace();
           }
       }
       new reqSend("a bunch of flowers", 1).start();
       new reqSend("a shiney new car", 2).start();
   }

   public static void main(String[] args) {
       new socTest();
   }

   public void run() {
       try {
           ServerSocket s = new ServerSocket(1108);
           s.setReuseAddress(false);
           while (true) {
               try {
                   Socket s1 = s.accept();
                   System.out.println("incoming request");
                   s1.setReuseAddress(false);
                   new reqRec(s1);
               } catch (IOException ex) {
                   ex.printStackTrace();
               }
           }
       } catch (IOException ex) {
           ex.printStackTrace();
       }
   }

   private class reqRec {
       public reqRec(Socket s) {
           try {
               System.out.println("req spawned");
               DataInputStream dis = new
DataInputStream(s.getInputStream());
               DataOutputStream dos = new
DataOutputStream(s.getOutputStream());
               String str = "";
               while (true) {
                   while (dis.available()==0) {
                       synchronized(this) {
                           notify();
                           wait(1);
                       }
                   }
                   str = dis.readUTF();
                   System.out.println(str);
               }
           } catch (Exception e) {
               System.out.println("dead");
           }
       }
   }

   private class reqSend extends Thread {
       String str;
       int id;
       public reqSend(String txt, int _id) {
           str = txt;
           id = _id;
       }

       public void run() {
           try {
               Socket s = new Socket("LocalHost", 1108);
               s.setReuseAddress(false);
               System.out.println("fetching streams");
               DataInputStream dis = new
DataInputStream(s.getInputStream());
               DataOutputStream dos = new
DataOutputStream(s.getOutputStream());
               int i = 0;
               while (i<100) {
                   synchronized(this) {
                       System.out.println(id + " - " + str + " send");
                       dos.writeUTF(str + i);
                   }
                   i++;
                   yield();
               }
               dos.flush();
                   s.close();
           } catch (Exception e) {
               e.printStackTrace();
               System.out.println("dead");
           }
       }
   }
}
Gordon Beaton - 08 Dec 2006 12:54 GMT
> I have a strange problem. I started work on software expecting that it
> was possible to create many client sockets in a single instance of a
> java program that connect to a single server where ever that maybe.

Your code is unnecessarily complex for the task, and somewhat
difficult to follow. Here are some suggestions:

- you are doing too much work in your constructors. Use the
 constructor to *initialise* the object. Invoke methods to *do*
 something with the object.

- drop all use of setReuseAddress(), it serves no purpose at all here.

- the normal way to delay execution is with Thread.sleep(). Calling
 notify() followed by wait() does not do what you seem to think, but
 you shouldn't be polling here anyway.

- I cannot see need for any synchronization (notify(), wait(), or
 yield()) in this code, and your use of these methods seems to
 indicate that you do not really understand what they do, or how to
 fix your program.

- there is no need to use available() before reading, in fact it will
 only cause you grief. You can replace your read loop with something
 more like this:

   try {
     while (true) {
       str = dis.readUTF();
       System.out.println(str);
     }
   catch (IOException e) {
     e.printStackTrace();
     System.out.println("dead");
   }

 The above loop could be made even simpler if you used a
 BufferedReader instead of a DataInputStream, since reaching EOF
 isn't really an exceptional event.

- your server fails to close the client socket after reaching EOF.
 Don't rely on GC for this, you *will* run out of descriptors.

- when a client calls connect(), it will succeed even though the
 server is not waiting in accept(), and it will be able to send a
 limited amount of data. However unless the server invokes accept(),
 there is nobody receiving the data, and the client will eventually
 block.

- after accepting a connection, do not simply invoke the reqRec
 constructor (most of which should be in a method anyway). After
 calling accept() the server must create a thread to handle each new
 client, so that it can go back to accept() as quickly as possible.

/gordon

Signature

[ don't email me support questions or followups ]
g o r d o n  +  n e w s  @  b a l d e r 1 3 . s e

dynaheir@hotmail.com - 08 Dec 2006 13:10 GMT
Thanks for your reply...

I hadn't realised I had implemented the handling code in the
constructor for this test case... it was intended to be a in the run
method. I was simply trying to see if 2 client sockets can connect to a
server socket from the same program as implied by the behaviour
exhibited in the actual program.

This change allows it to work but proves there's a different issue
causing my actual program to fail.

Thanks for your help.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.