I'm building a GUI application which needs to have a TCP Server running. The GUI is built in Swing. The trouble I'm having is running the server. I want to have one desktop application people can install, that will in turn start the server for me. The server is blocking while it runs ie:
while (true) {
Socket client = serverSocket.accept();
System.out.println("S: Receiving...");
....
I tried to call the server class, but then it blocks the GUI. What do you think is the best way to separate the Server from the GUI, while easily being able to package both together? Thanks for any help!
There are two basic approaches to socket programming in Java:
Use one thread per Socket
Use Non-Blocking IO in one or a small number of threads
You probably want the first one. If you don't know which one you want, then you almost certainly want the first one. This is subjective, but I think most people would agree #1 is easier to get correct.
Here's an answer that discusses the difference.
Assuming you decide to go with threads, use a thread pool! It's easy and tidy.
I think you're past this stage, but if you want some basic "101" type material, the old Sun tutorial on Sockets and Threads is dusty but useful.
Threads.
Note that once you introduce multi-threaded programming, there are a lot of gotchas. One important one is that access to any Swing or GUI element must be done in the Swing Event Thread. You can use SwingWorkers to make that task easier.
You can also use Java NIO.
The easiest solution is generally to run your ServerSocket in a different thread. You may also try things like asynchronous IO, but it's a real pain.
Well, from your description, perhaps the problem is that you need to put the GUI and the server part (with that while(true) ), into separate Threads, so that you can handle user generated events.
Simplest thing is building your server in separate thread.
Related
I am having trouble developing a chat application including file sharing. It's a server and client based desktop application. I am able to develop chat and also file sharing individually.
Now I want merge two project and having problem. Is it possible to use multiple socket in single thread like main thread? Or do I have to use one for chatting and another for file sharing?
I think that is possible but in the same thread one operation with one socket have to wait all the operations from annother finish. if you want the two operations execute at the same time do it in different threads.
Hope that helps :)
Yes it is possible for a single thread to use multiple sockets. See the Selector API.
The basic idea is that the code in your thread needs to know about all of the selectable channels (sockets, open files, etc) that it needs to read from or write to. It registers the channels with the selector. Then you make a select call which will (for example) block until one of the registered channels is ready; e.g. a socket that has data that can be read now ... without blocking.
It is complicated, but rather than explaining it all here, I suggest that you read Baeldung's Introduction to the Java NIO Selector which includes an example.
But the bottom line is that using Selector will probably entail significant restructuring of your existing code. And if your code is using (for example) a 3rd-party library to do the I/O, then this approach probably won't work. Using multiple threads may well be a simpler option.
I am developing an application that entails a single server, and a large number of clients. I'm utilizing the Java socket programming APIs to accomplish this task. At the moment, I am considering restructuring the entire design of my application because I simply do not think that it is structured in the most efficient way, and would appreciate some guidance towards an optimal path.
Current Implementation
I have one ServerSocket located on port 5000, and the thread that contains the socket simply runs continuously and accepts any connection. It then starts up a new server thread (based on a synchronized table of available ports) that handles communication with that client, and then blocks for ServerSocket.accept() again.
The threads that are spawned from this main thread also contain a ServerSocket and are used as a means to handle multiple connections at once.
Now, the client thread simply connects to port 5000, receives the next available port as a reply, then disconnects from port 5000 (by calling Socket.close()), and reconnects to the port that the server said was available.
My Question
Is this the most optimal way (or better yet, is it even reasonable?) to handle multiple clients on a single server? Or should I simply open ServerSocket's on all available ports and just listen constantly? Perhaps something that I have not yet considered?
Addendum
I'm trying to think in terms of very large client-server applications such as MMORPGs or some chat application to get a feeling for my implementation's feasibility. For example, I try to ask myself: "Although this might work, would it be a good solution if this application had a large user-base?". That being said, it would be easier for me to understand the optimal nature of a solution if I could see how it would work on a large scale, with say, millions of users.
I don't understand why you would need to use a new ServerSocket each time the main one accepts a connection. Why don't you simply use the socket returned by accept() (as explained in the Java tutorial)?
Also, instead of starting a new thread for each client, you should use a thread pool. This would avoid constant creations of new threads, and would avoid starting too many threads and bring your server to its knees.
This architecture is not the best one to handle a huge number of users, though. Using asynchronous IO would probably be a better solution if you really need such a scalability, but I don't have much experience with that.
When thinking of server architecture, the first question is to estimate how much memory and precessing power is required for single connection. The second is the number of simultaneous connections. After multiplication, we can decide if single machine is sufficient or we need a cluster.
Then we decide if we can afford a thread (some 128..512 KBytes) for a connection. If we can, then classic one-thread per-connection is OK. If we cannot, then async architecture based on NIO or NIO2 is more suitable.
After the basic decisions are done, we can select appropriate libraries and frameworks. Doing everything from scratch is more interesting, but would take so much time that the result may be interesting to nobody at the moment it is achieved.
I agree with your following suggestion because the single server on port 5000 is a bottleneck:
Or should I simply open ServerSocket's on all available ports and just
listen constantly?
I prefer the pool of serversocket.
Use JMS (in my case its ActiveMq) achieve you target. You can have load balancing and fail over easily
Ive been reading for the past few days about the difference between io and nio when building a java socket server. for my use i need a server which can run lots of connections and ion supposed to do the trick.
My only fear is that it a bit slower and a bit harder to implement instead of running a thread for each connection. so i thought why dont i use the same easiness of threads and the logic of java.nio and build a server has a thread which checks all the open connection and when ever there is a new event, it will open a new thread for handing it. i think in that way im enjoying both of the worlds... what do u suggest?
NIO almost entirely relies on JNI, so if you want to implement it again, you'll actually have to write loads of C/++ and OS API interface code.
I think the existing Java implementations are already quite good. For example, the Selector class wraps the system call for waiting on multiple file descriptors. There's hardly anything you can do to improve the efficiency of that.
I suggest you don't understand the point of NIO, which is to only use one thread. It is certainly complex and it is arguable whether you have any need for it at all below 1000 clients, probably 10,000, possibly even 100,000. I would implement your server with java.net to get it running and save java.nio for phase 2 if you ever get there and prove to yourself that you really need it.
EDIT: I would certainly forget this concept of rolling your own. You're wildly underestimating the task (It took Sun 1.4.0, 1.4.1, 1.4.2 before it really worked properly), and you seem to be aiming to get the worst of both worlds. You won't be able to get any more out of it than Sun did with java.nio, as there isn't any more. Arguably a bit less ;-)
I'm just looking for some insight into program design, since I'm not that experienced with threads.
Currently programming a little client. You can specify if that client is the "server" or "client" and it will create the protocols in the correct manner.
I do a little handshake between them (a syn, ack, synack sort of thing) and then start the network thread.
I have the main thread, who has an infinite while loop and does two things.
Adds a message to a "toSend" queue.
Pulls in all the messages from the "received" queue and prints them.
The network thread has an infinite while loop that does two things.
Pulls in all the messages from the "toSend" queue and sends them.
Adds a message to the "received" queue (that was fetched).
The queues are currently ArrayBlockingQueue<String>(1000)
My question is the following:
Is this towards a good design of a network thread? Are there any gotchas I need to handle?
Currently I've had an issue where one of the threads (the main thread) is filling the "toSend" queue even before the network thread has a chance to send even one message. I've "handled" this by making the main thread do some work that blocks (I/O).
It seems like you are re-inventing the wheel and are struggling with issues others have solved (and most probably with an optimized solution) before, please take a look at Netty:
The Netty project is an effort to provide an asynchronous event-driven network application framework and tools for rapid development of maintainable high performance & high scalability protocol servers & clients.
There is an example for an broadcast UDP/IP client and server.
Personally I think that handling UDP networking is best done using a single threaded, event driven programming style, rather than using threads. It is stateless anyhow, so it makes little sense trying to track the state in a thread.
Things like timeouts are easily handled with timers adding events to the event queue.
This effectively sidesteps all the synchronisation issues.
I have been working on UDP/TCP real time systems for more than 4 years now.
Your question has a lot of sense. In my humble opinion, the Netty framework is a good way to go but a bit heavy.
I am using the exact same design that you mentioned and have seen no issues with it so far.
Regards,
The 'toSend' queue is pointless. Just have everybody send directly via the socket.
I can create multiple threads for supporting multi-client feature in socket programming; that's working fine. But if 10,000 clients want to be connected, my server cannot create so many threads.
How can I manage the threads so that I can listen to all these clients simultaneously?
Also, if in this case the server wants to send something to a particular client, then how is it possible?
You should investigate Java's NIO ("New I/O") library for non-blocking network programming. NIO was designed to solve precisely the server scalability problem you are facing!
Introductory article about NIO: Building Highly Scalable Servers with Java NIO
Excerpts from O'Reilly's Java NIO book
Highly scalable socket programming in Java requires the selectable channels provided in the "New I/O", or NIO packages. By using non-blocking IO, a single thread can service many sockets, tending only to those sockets that are ready.
One of the more scalable open-source NIO applications is the Grizzly component of the Glassfish application server. Jean-Francois Arcand has written a number of informative, in-depth blog posts about his work on the project, and covers many subtle pitfalls in writing this kind of software with NIO.
If the concept of non-blocking IO is new to you, using existing software like Grizzly, or at least using it as a starting point for your adaptation, might be very helpful.
The benefits of NIO are debatable. See Paul Tyma's blog entries here and here.
A thread-per-connection threading model (Blocking Socket I/O) will not scale too well. Here's an introduction to Java NIO which will allow you to use non-blocking socket calls in java:
http://today.java.net/cs/user/print/a/350
As the article states, there are plenty of frameworks available so you don't have to roll your own.
As previously mentioned, 10.000 clients is not easy. For java, NIO (possibly augmented with a separate threadpool to handle each request without blocking the NIO thread) is usual way to handle a large amount of clients.
As mentioned, depending on implementation, threads might actually scale, but it depends a lot on how much interaction there is between client connections. Massive threads are more likely to work if there is little synchronization between the threads.
That said, NIO is notoriously difficult to get 100% right the first time you implement it.
I'd recommend either trying out, or at least looking at the source for the Naga NIO lib at naga.googlecode.com. The codebase for the lib is small compared to most other NIO frameworks. You should be able to quickly implement a test to see if you can get 10.000 clients up and running.
(The Naga source also happens to be free to modify or copy without attributing the original author)
This is not a simple question, but for a very in depth (sorry, not in java though) answer see this: http://www.kegel.com/c10k.html
EDIT
Even with nio, this is still a difficult problem. 10000 connections is a tremendous resource burden on the machine, even if you are using non-blocking sockets. This is why large web sites have server farms and load balancers.
Why don't you process only a certain amount of requests at a time.
Let's say you want to process a maximum of 50 requests at a time (for not creating too many threads)
You create a threadpool of 50 threads.
You put all the requests in a Queue (accept connections, keep sockets open), and each thread, when it is done, gets the next request then process it.
This should scale more easily.
Also, if the need arise, it will be easier to do load balancing, since you could share your queues for multiple servers
Personally I would rather use create a custom I/O non blocking setup, for example using one thread to accept clients and using one other thread to process them (checking if any input is available and writing data to the output if necessary).
You'll have to figure out why your application is failing at 10,000 threads.
Is there a hard limit to the number of threads in the JVM or the OS? If so, can it be lifted?
Are you running out of memory? Try configuring a smaller stack size per thread, and/or add more memory to the server.
Something else? Fix it.
Only once you have determined the source of the problem will you be able to fix it. In theory 10,000 threads should be OK but at that level of concurrency it requires some extra tuning of the JVM and operating system if you want it to work out.
You can also consider NIO but I think it can work fine with threads as well.