简体   繁体   中英

What is an appropriate architecture for creating a multi-user client-server application?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM