Java and Client/Server

So you think client-server programming is only for large applications?
The Server

The server is a simple single-process concurrent server. Simply put, the server polls each connection, and processes requests in order. An alternative would be to fork a new process for each incoming connection. In this situation the single process server is far simpler (and, after all, the computer can only really do one thing at a time). The basic order of things is:

  1. Create the master socket on the well-known port.

  2. Bind the socket so that incoming requests are directed to the proper place.

  3. Listen for connections.

  4. Accept incoming connections.

The “well-known port” is a port which is known to all clients. All clients can't connect to the same port, so the server “hands off” connection requests to a different port. This is done by the TCP/IP layer, and we don't need to concern ourselves about how. This process is analogous to that of making a phone call to a large corporation's toll free number. Suppose that you wish to call 1-800-257-1234. You are asking the server for a connection on that port (phone) number. This company probably has hundreds of lines, but you would not want to try each of them until you finally got through, so the corporation has set up a rotary on their lines to put connections through to the next available phone line.

TCP/IP sockets work the same way. When a connection is accepted on a socket, a new file descriptor is created. The file descriptor is used as an index to an array of structures. Every client has exactly one unique file descriptor and a slot in the client array. Each array position holds a structure which contains the handle and current channel number. When the server receives a message packet, it looks through the entire array and retransmits the message to all clients who are subscribed to the channel number that the message came from.

Currently supported server commands are:

  • CB_ON sets the client's channel to 19 and sends a welcome message. It also stores the handle in the client array.

  • CB_OFF closes the socket and clears the client info from the client array.

  • SET_CHAN changes the channel of the client in the client array.

  • WHO_CHAN sends a message containing the handles of all connected clients subscribed to the current channel.

  • SEND-MESSAGE sends the message contained in the message field of the data packet to each client subscribed to the same channel as the originator. Emergency traffic on channel 9 is also sent to all connected clients regardless of what channel they are subscribed to. As stated earlier, the server must have all bytes in the data packet sent or received at once. It is not possible (with this implementation) to send part of a packet.

The Client

My original goal was to make a client that looked like a CB radio panel. This turned out to be too difficult to do with Java; while Java is a good portable programming language, creating a complex user interface is very difficult. I adapted my client from an example in Java in a Nutshell by David Flanagan, O'Reilly & Associates (an excellent book—great for reference). The CB client user interface is very simple. A Connect menu is at the top. From here, the user can quit or ask the server who is on the current channel. The middle window is the message area. Here all messages from other users and the server are listed. The client will print the handle and message from the data packet. The server is responsible for the data in those packets as it will put “System: WHO” in the handle for a WHO request. The bottom field is for entering a new channel. When Java detects activity in the menu bar or channel field, it will call the event handler routine. From here, it determines where the event came from and performs the appropriate processing. The user interface is not much—more a “proof of concept” than anything else—but it does provide much more functionality in fewer lines of code than would be required by an equivalent program written in C.

Endian Wars

The big vs. little endian debate has been the topic of many flame wars on the Internet. But what is it? Big and little endian refers to the order of bytes. When moving data around, some systems start with the most significant byte (MSB) and some start with the least significant byte (LSB). Imagine an array of 4 bytes. How do you store or send this array? Would you start at the LSB (little endian) or would you start at the MSB (big endian)? Some hardware does it one way, and some does it the other. Why do we care? If you are writing a client and server in C to run on the same type of hardware, the endian problem doesn't pop up. But if you are using a different language, like Java, to talk to a server written in C, there could be a big problem. Endian problems crop up only when multiple byte data types like integers are sent across the network. Java automatically converts its data to and from network byte order when it sends data through a socket. C, on the other hand, does only as it is told. There are two C system calls, ntohl() and htonl(), which convert data to and from network byte order. Read the man pages for these calls and use them in your C-based servers and clients to avoid endian problems.

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

C does have threads

ansa256's picture

C does not have threads? I think it does, I've been working with threads in C for quite a long time, POSIX threads especifically (-lpthread flag for gcc).

Threads

Mitch Frazier's picture

Bad info in this article, of course C has threads. What C doesn't have is "built-in" support for threads and concurrency. Java on the other hand does provide language level constructs for such things.

Mitch Frazier is an Associate Editor for Linux Journal.

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix