•
•
•
•
What is DaniWeb IT Discussion Community?
You're currently browsing the Java section within the Software Development category of DaniWeb, a massive community of 402,044 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 2,465 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our Java advertiser: Lunarpages Java Web Hosting
Views: 824 | Replies: 18 | Solved
![]() |
If you were knowledgeable about how Servers operated in Java, you wouldn't have this problem.
Really, this is nothing more than I/O with either streams or packets.
The scenario can be one of many.
If you're the Server, you wait for incoming Clients. The server can support a finite number of clients at its current location. You specify a port number for the Server to use, and typically the port number is set to a number that is not in use and that is valid.
If you're a Client, you can connect to a Server. The Client specifies the IP address the Server is located at and the port number. The IP address, I suppose is the home-base of the Server and the port number is the valid port number the Server is using.
Yes, this means you can have multiple Servers on one computer (by specifying different ports at the same IP).
Yes this means you can have multiple Clients per Server (where each client's action is listened for by the Server).
I do not know if a pure Client-to-Client connection can be made (in theory it seems possible but I haven't tried it yet) but unless you're incredibly proficient with Client/Servers I wouldn't recommend it (biased opinion since I'm fairly new to this myself).
What I do know is that if you want to make your program accept multiple Servers, and do so Concurrently, I'd assume that you would provide a Threaded Client that had a reference to a non-null server, where the non-null server would block and wait for the Client to connect.
This is a guess based on what I know about Client/Servers (just recently covered it in a class). Basically the Server will be capable of blocking for two Clients and accept communications from both at the same time through separate input and output stream handles to the specific Clients.
Each Client (Socket, or any class that derives from the Socket class) has something called getInputStream and getOutputStream methods. These methods are particularly useful for directly sending or receiving information from the Streams of the Clients. The Server can use these to communicate with the Clients by (if your Server is your main application) stuffing information in a Stream continuously and/or receiving information from a Stream continuously. Which Stream the Server looks at is entirely up to you. You'll just need to be in an environment capable of constantly checking the input and output streams of the Clients (through a while loop, a swing object, or a personal dedicated Thread for doing so).
Now to send and receive information seems in reverse to what you do with File I/O. The Server acts like the "receiving file" and the Client acts as a user that's writing and/or reading information to the file.
For example, the Client's output stream is the data the client is receiving as output, and the Client's input stream is the Client's way of sending information via input.
Understanding this concept is fundamental. Basically if the Client's way of sending information is the input stream, we can intercept it as the Server and find out what it is sending by waiting for information returned by the input stream (a call to the Client's input stream usually blocks until information is entered in the stream - basically you're like a file waiting for information to be written to you, is you're the Server). If we want the Client to see information, we can intercept the output stream for the specific Client and send information to the Client.
Now if you understand the concept of---
-Running Multiple Threads.
-How the Server works.
--mentioned above, You should be capable of establishing a multi-threaded environment for your Client/Server.
You may (or may not) have to do the research, but the concept is fairly obvious. I'll leave it to you to figure it out. Good luck!
Really, this is nothing more than I/O with either streams or packets.
The scenario can be one of many.
If you're the Server, you wait for incoming Clients. The server can support a finite number of clients at its current location. You specify a port number for the Server to use, and typically the port number is set to a number that is not in use and that is valid.
If you're a Client, you can connect to a Server. The Client specifies the IP address the Server is located at and the port number. The IP address, I suppose is the home-base of the Server and the port number is the valid port number the Server is using.
Yes, this means you can have multiple Servers on one computer (by specifying different ports at the same IP).
Yes this means you can have multiple Clients per Server (where each client's action is listened for by the Server).
I do not know if a pure Client-to-Client connection can be made (in theory it seems possible but I haven't tried it yet) but unless you're incredibly proficient with Client/Servers I wouldn't recommend it (biased opinion since I'm fairly new to this myself).
What I do know is that if you want to make your program accept multiple Servers, and do so Concurrently, I'd assume that you would provide a Threaded Client that had a reference to a non-null server, where the non-null server would block and wait for the Client to connect.
This is a guess based on what I know about Client/Servers (just recently covered it in a class). Basically the Server will be capable of blocking for two Clients and accept communications from both at the same time through separate input and output stream handles to the specific Clients.
Each Client (Socket, or any class that derives from the Socket class) has something called getInputStream and getOutputStream methods. These methods are particularly useful for directly sending or receiving information from the Streams of the Clients. The Server can use these to communicate with the Clients by (if your Server is your main application) stuffing information in a Stream continuously and/or receiving information from a Stream continuously. Which Stream the Server looks at is entirely up to you. You'll just need to be in an environment capable of constantly checking the input and output streams of the Clients (through a while loop, a swing object, or a personal dedicated Thread for doing so).
Now to send and receive information seems in reverse to what you do with File I/O. The Server acts like the "receiving file" and the Client acts as a user that's writing and/or reading information to the file.
For example, the Client's output stream is the data the client is receiving as output, and the Client's input stream is the Client's way of sending information via input.
Understanding this concept is fundamental. Basically if the Client's way of sending information is the input stream, we can intercept it as the Server and find out what it is sending by waiting for information returned by the input stream (a call to the Client's input stream usually blocks until information is entered in the stream - basically you're like a file waiting for information to be written to you, is you're the Server). If we want the Client to see information, we can intercept the output stream for the specific Client and send information to the Client.
Now if you understand the concept of---
-Running Multiple Threads.
-How the Server works.
--mentioned above, You should be capable of establishing a multi-threaded environment for your Client/Server.
You may (or may not) have to do the research, but the concept is fairly obvious. I'll leave it to you to figure it out. Good luck!
•
•
Join Date: Jul 2008
Posts: 92
Reputation:
Rep Power: 1
Solved Threads: 0
The concept isn't hard to understand. I don't take a class, but I researched it all myself and that isn't the problem I am having. My goal was to make 1 server, and run multiple clients. Not multiple servers, and I didn't even expand over the simple network yet.
Currently, I have one computer trying to connect all clients to a server.
IP is just local host, because I am only doing it on my own computer. What I don't get is why new threads aren't forming after one client connects.
I thought it was the server's job to start new threads, but okay, I will give it a go with the clients. Although the user before said something was incorrect with my server code.
I picked up Java on my own, and started around June, so I am not exactly sure what he meant by debugging. I mean, there are no errors in the program, so I don't exactly understand how debugging will aid me. It just runs the program for me.
Currently, I have one computer trying to connect all clients to a server.
IP is just local host, because I am only doing it on my own computer. What I don't get is why new threads aren't forming after one client connects.
I thought it was the server's job to start new threads, but okay, I will give it a go with the clients. Although the user before said something was incorrect with my server code.
I picked up Java on my own, and started around June, so I am not exactly sure what he meant by debugging. I mean, there are no errors in the program, so I don't exactly understand how debugging will aid me. It just runs the program for me.
•
•
Join Date: Jan 2008
Posts: 1,490
Reputation:
Rep Power: 6
Solved Threads: 187
•
•
•
•
The concept isn't hard to understand. I don't take a class, but I researched it all myself and that isn't the problem I am having. My goal was to make 1 server, and run multiple clients. Not multiple servers, and I didn't even expand over the simple network yet.
Currently, I have one computer trying to connect all clients to a server.
IP is just local host, because I am only doing it on my own computer. What I don't get is why new threads aren't forming after one client connects.
I thought it was the server's job to start new threads, but okay, I will give it a go with the clients. Although the user before said something was incorrect with my server code.
I picked up Java on my own, and started around June, so I am not exactly sure what he meant by debugging. I mean, there are no errors in the program, so I don't exactly understand how debugging will aid me. It just runs the program for me.
It looks to me like the server only creates one socket and uses one port at a time. One guest program and one server program connect through that socket. I'm no expert on sockets and I could be off, but I don't think a third program can join a socket that's already being used between two other programs. Seems to me that if you have two clients, you need two sockets and two ports. If you have three clients, you need three sockets and three ports. Do you ever create a second socket? I don't see anywhere on the server's GUI where it can specify a second port to use for a second socket. I'm still figuring out why exactly it says "Connected" when the second client tries to join the original socket, but I don't think it is actually connected. If you're only using one port, I think you can only have one socket, and if you only have one socket, I think you can only have one client. Like I said, my knowledge of sockets is somewhat limited, but I think that's the way it is and I don't see the GUI allowing the server port ever to change without the server breaking the original socket's connection.
•
•
•
•
The concept isn't hard to understand. I don't take a class, but I researched it all myself and that isn't the problem I am having. My goal was to make 1 server, and run multiple clients. Not multiple servers, and I didn't even expand over the simple network yet.
Currently, I have one computer trying to connect all clients to a server.
IP is just local host, because I am only doing it on my own computer. What I don't get is why new threads aren't forming after one client connects.
I thought it was the server's job to start new threads, but okay, I will give it a go with the clients. Although the user before said something was incorrect with my server code.
I picked up Java on my own, and started around June, so I am not exactly sure what he meant by debugging. I mean, there are no errors in the program, so I don't exactly understand how debugging will aid me. It just runs the program for me.
What I do know is that if you want to make your program accept multiple Clients, and do so Concurrently, I'd assume that you would provide a Threaded Client that had a reference to a non-null server, where the non-null server would block and wait for the Client to connect.
I goofed - I meant multiple clients @_@
•
•
Join Date: Jan 2008
Posts: 1,490
Reputation:
Rep Power: 6
Solved Threads: 187
•
•
•
•
OKay thanks. I will look into that, fooling around with multiple sockets.
Let me actually clarify/correct my previous post, and reiterate that I'm somewhat out of my league on sockets. I've written a single-server, multi-client socket program successfully, but usually screw up a few times in the process and get Socekt and ServerSocket confused, so I'm going to offer this post and then shut up. Your ServerSocket should keep the same port for clients to try to connect to. Each time ServerSocket.accept() is executed, a new Socket should be created by the ServerSocket. That Socket will be assigned a port. All further message passing should go down that Socket, so that Socket can't have port 1337, since that's the ServerSocket's port, and all new Sockets need to have different ports from each other and different ports from 1337. Put some debugging statements in to make sure that's the case. So I think that if you have three programs going and connecting, you end up with five different ports used and two sockets total. The server uses three of the ports (1337 plus two random ones chosen by Java and not specified by you, let's say 1338 and 1339) and client 1 will have a different port, say 1340, and client 2 will have a different port, say 1341. The only port you've specified is 1337.
Socket 1 will connect ports 1338(server) and 1340(client 1).
Socket 2 will connect ports 1339(server) and 1341(client 2).
Port 1337 is reserved for the initial connection and remains the same since the clients need to have a constant port to connect to.
I can't get your program to run at all now, even with one client, which is weird since it worked before, so I can't verify this, so let me add again that I'm no socket pro so double-check with the documentation. But also check out this link towards the bottom. Best of luck.
http://java.sun.com/docs/books/tutor...entServer.html
Ok, here is a small example of a multi-threaded server that I was playing around with a little while working on an auto-update launcher for an app here, maybe it will help. "Launcher" is the client portion. Each needs to be run separately on the same machine (since the client is connecting to localhost in the example)
Server:
Client:
Server:
java Syntax (Toggle Plain Text)
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.*; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class Server { final static int PORT = 12100; Thread processThread; public Server() { try { processThread = new ProcessThread(new ServerSocket(PORT)); processThread.start(); } catch(IOException ex) { ex.printStackTrace(); } } private class ProcessThread extends Thread { ServerSocket server; ExecutorService requestPool; public ProcessThread(ServerSocket server){ this.server = server; requestPool = Executors.newCachedThreadPool(); } public void run() { try { System.out.println("server waiting to process.."); while(true) { Socket sock = server.accept(); // start an UpdateTask for this client requestPool.submit(new UpdateTask(sock)); sleep(100); } } catch(IOException ex) { ex.printStackTrace(); } catch(InterruptedException e) { // Disable new tasks from being submitted requestPool.shutdown(); try { // Wait a while for existing tasks to terminate if (!requestPool.awaitTermination(60, TimeUnit.SECONDS)) { // Cancel currently executing tasks requestPool.shutdownNow(); // Wait a while for tasks to respond to being cancelled if (!requestPool.awaitTermination(60, TimeUnit.SECONDS)) System.err.println("Pool did not terminate"); } } catch (InterruptedException ie) { // (Re-)Cancel if current thread also interrupted requestPool.shutdownNow(); // Preserve interrupt status Thread.currentThread().interrupt(); } Thread.currentThread().interrupt(); } } } public void shutdown(){ if (processThread != null && processThread.isAlive()){ processThread.interrupt(); } } /** This is the task that will be executed for each client * on the CachedThreadPool */ private class UpdateTask implements Callable<String> { Socket client; String clientName; public UpdateTask(Socket client){ this.client = client; } public String call() throws Exception { BufferedReader rd = new BufferedReader( new InputStreamReader(client.getInputStream())); PrintWriter wr = new PrintWriter( new OutputStreamWriter(client.getOutputStream()),true); // process input from the client String str; while ((str = rd.readLine()) != null) { System.out.println(str); if (str.endsWith("calling")){ clientName = str.substring(0,str.indexOf(" calling")); wr.println("Go ahead, "+clientName); } if (str.startsWith("update")){ wr.println("updating "+clientName); } if (str.startsWith("got it")){ wr.println("bye "+clientName); } } rd.close(); System.out.println(clientName+" finished"); return "Ok, done"; } } public static void main(String[] args) { new Server(); } }
java Syntax (Toggle Plain Text)
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.net.SocketTimeoutException; import java.net.UnknownHostException; public class Launcher { final static int PORT = 12100; String client; public Launcher(String client) { this.client = client; // Create a socket with a timeout try { InetAddress addr = InetAddress.getByName("localhost"); int port = 12100; SocketAddress sockaddr = new InetSocketAddress(addr, port); // Create an unbound socket Socket sock = new Socket(); // This method will block no more than timeoutMs. // If the timeout occurs, SocketTimeoutException is thrown. int timeoutMs = 2000; // 2 seconds sock.connect(sockaddr, timeoutMs); System.out.println(client+" connected"); PrintWriter wr = new PrintWriter( new OutputStreamWriter(sock.getOutputStream()), true); BufferedReader rd = new BufferedReader( new InputStreamReader(sock.getInputStream())); // send something to server wr.println(client+" calling"); // read server response String str; while((str = rd.readLine())!=null) { System.out.println(str); if (str.startsWith("Go ahead")){ wr.println("update me"); } if (str.startsWith("updating")){ wr.println("got it"); } if (str.startsWith("bye")){ break; } } rd.close(); wr.close(); sock.close(); } catch(UnknownHostException e) { e.printStackTrace(); } catch(SocketTimeoutException e) { e.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } } public static void main(String[] args) { // start up two client threads new Thread(new Runnable() { public void run() { new Launcher("Bob"); } }).start(); new Thread(new Runnable() { public void run() { new Launcher("Mary"); } }).start(); } }
I know the answer was probably already given but I made this simple chatting program from scratch.
It is a test - it does NOT cover things such as recycling threads that are no longer used when a client disconnects, nor is there any true exception handling when a client disconnects.
Also there is a flag-type system in this practice program that disables the same input from being entered twice. That can easily be removed, but it was only implemented because the original program (modified) sent information to the Server as if it were a type of information-storage unit (or a very watered down database).
Here's the code.
It can use a lot of work but it gets some of the main points of network + multi-threading across.
Edit: Looking back at the code, I think that the call to accept() should not be synchronized, but the increment of index should be at least.
It is a test - it does NOT cover things such as recycling threads that are no longer used when a client disconnects, nor is there any true exception handling when a client disconnects.
Also there is a flag-type system in this practice program that disables the same input from being entered twice. That can easily be removed, but it was only implemented because the original program (modified) sent information to the Server as if it were a type of information-storage unit (or a very watered down database).
Here's the code.
java Syntax (Toggle Plain Text)
import java.io.*; // for ObjectInputStream and ObjectOutputStream classes import java.net.*; // for Socket and ServerSocket classes import java.util.*; // for a Scanner object import java.util.concurrent.*; // for Executors and ExecutorService classes public class ChatServer{ private ServerSocket ss; private Socket theClient[]; private ObjectInputStream ois[]; private ObjectOutputStream oos[]; private ChatServer cs = this; private String information = "No information", oldInformation = "No information"; private boolean update = false; private static int numClients = 0; private int index = 0; static{ System.out.println("Setting up a test server..."); System.out.println("How many clients would you like to connect to the server? "); numClients = new Scanner(System.in).nextInt(); } private ExecutorService es; public static void main(String... args){ ChatServer myCS = new ChatServer(); while(true){ if(!myCS.information.equalsIgnoreCase(myCS.oldInformation)){ myCS.oldInformation = new String(myCS.information); myCS.update = true; } for(ObjectOutputStream element : myCS.oos){ if((element != null) && myCS.update){ try{ element.writeObject(myCS.information + "\n"); }catch(Exception e){e.printStackTrace();} }else continue; } myCS.update = false; } } public ChatServer(){ /* * Server should block for clients * and wait for a connection of at least * one client before displaying information */ try{ ss = new ServerSocket(6000, numClients); // creates the server at this address, with port 6000 and portQueue numClients theClient = new Socket[numClients]; // makes room for numClients amount of clients ois = new ObjectInputStream[numClients]; // makes room for numClients amount of ObjectInputStreams oos = new ObjectOutputStream[numClients]; // makes room for numClients amount of ObjectOutputStreams es = Executors.newFixedThreadPool(numClients); }catch(Exception e){e.printStackTrace(); System.exit(1);} // prints the location of the Exception for(int i = 0; i < numClients; i++){ try{ es.submit(new MyThread()); }catch(Exception e){e.printStackTrace();} } } private void sleep(long milliseconds){ try{Thread.sleep(milliseconds);}catch(Exception e){} } private class MyThread implements Runnable{ int x = 0; @Override public void run(){ /*Aquires a lock for the out-class - locks other threads from executing until this automic action is finished*/ synchronized(cs){ x = index++; System.out.println(x); try{ theClient[x] = ss.accept(); oos[x] = new ObjectOutputStream(theClient[x].getOutputStream()); oos[x].flush(); ois[x] = new ObjectInputStream(theClient[x].getInputStream()); }catch(Exception e){e.printStackTrace();} } while(true){ System.out.println("Blocking for client number: " + x); try{ information = (String)ois[x].readObject(); System.out.println("Got new information!"); }catch(Exception e){e.printStackTrace();} } } } }
java Syntax (Toggle Plain Text)
import java.io.*; import java.net.*; import java.util.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.concurrent.*; public class SomeClient extends JFrame implements ActionListener{ private Socket me; private ObjectInputStream ois; private ObjectOutputStream oos; private JTextArea jta; private JTextField jtf; private ExecutorService es; public SomeClient(){ setSize(600, 400); setLayout(new BorderLayout()); jta = new JTextArea(); jta.setEditable(false); add(BorderLayout.CENTER, jta); jtf = new JTextField(30); jtf.setEditable(true); jtf.setActionCommand("JTF"); jtf.addActionListener(this); add(BorderLayout.SOUTH, jtf); try{ me = new Socket("127.0.0.1", 6000); oos = new ObjectOutputStream(me.getOutputStream()); oos.flush(); ois = new ObjectInputStream(me.getInputStream()); }catch(Exception e){e.printStackTrace();} es = Executors.newFixedThreadPool(1); es.submit(rt); } Runnable rt = new Runnable(){ @Override public void run(){ while(true){ try{ jta.append((String)ois.readObject()); }catch(Exception e){e.printStackTrace();} } } }; public static void main(String... args){ SomeClient sc = new SomeClient(); sc.setVisible(true); } public void actionPerformed(ActionEvent e){ if(e.getActionCommand().equalsIgnoreCase("JB")){ } else if(e.getActionCommand().equalsIgnoreCase("JTF")){ try{ oos.writeObject("<" + me.toString() + "> " + jtf.getText()); oos.flush(); jtf.setText(""); }catch(Exception e2){e2.printStackTrace();} } } }
It can use a lot of work but it gets some of the main points of network + multi-threading across.
Edit: Looking back at the code, I think that the call to accept() should not be synchronized, but the increment of index should be at least.
Last edited by Alex Edwards : Jul 27th, 2008 at 1:17 am.
![]() |
•
•
•
•
•
•
•
•
DaniWeb Java Marketplace
•
•
•
•
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)



