Java and Client/Server
Client-server applications are everywhere. Client-server can be defined as a process which provides services to other processes. The client and server can be run on the same machine or on different machines on opposite sides of the world. A non-programming example of a client-server situation is the telephone system. You are the client (or customer) and the central office is the server. By having a telephone connected to the system (and your bill current!) you are subscribing to the services that the central office provides. Requests are made of the server (central office) to place and receive calls. The server also does accounting on each call made or received and handles emergency (911) requests. In this article I will present a simple CB (citizen's band) radio simulator which was written for a class project. The server is written in C and the client is written in Java. I will assume that the reader understands what sockets are and has a rough idea of how they are used.
The specifications for the project were loosely:
Provide a server which can accept multiple simultaneous connections. The server should have a basic command set that will open and close the connection, change the channel and provide a list of current clients on a specific channel.
Provide an “emergency channel” (9) that will broadcast all traffic to all currently connected clients regardless of which channel they are subscribed to.
Client should “come up” on channel 19. This is the channel where CBers meet. They then agree which channel to move to in order to continue their conversation.
The client should display all traffic on the current channel with the handle of the person who sent the message.
The server can be either a single process concurrent or multiple process server (more on this later).
Besides getting extra credit for doing a graphical user interface, I chose Java in order to simplify programming of the client. Java is used specifically for the following reasons:
Portability. I was developing code at home on my Linux system and running the code on Suns at school.
Functionality. Not just for web page animations, Java is a very useful programming language. Java is object-oriented and very similar to C and C++. A simple user interface is relatively easy to write.
Threads. Java allows multiple threads (like a background process) of execution. A thread can be launched that will listen for incoming messages. When a message comes in, it is automatically sent to output. We start this thread and forget about it.
Can be run remotely from Netscape (or similar browser). While I have not currently implemented this feature, conceivably, web surfers looking at your page could talk to each other using the CB simulator. There are many restrictions to this which we will go into later.
Using C for the client would require more programming to accomplish the same results. First, some sort of GUI builder like Motif or X-Forms would need to be used. I'm not knocking any of these, but not every system has them and they can be difficult to learn and use. C does not have threads, so all I/O would have to be polled. User input as well as incoming messages would have to be polled and processed accordingly. Without a GUI, some type of command codes would have to be developed for the user to control the client and server. This would probably be very cryptic and difficult to use—not to mention difficult to implement.
I developed the server first, from the specification in Table 1. Messages are fixed length and must not vary from the given format. C handles transmissions well through the use of structures and pointers; basically, you just call a write or read routine, passing a pointer to the data structure, and the bytes come or go without much of a problem. This works fine for C; Java is another story.
Sockets work almost the same in Java as their counterparts in C. Since Java is object-oriented, you must create an instance of the socket object. This is done by a simple line of code:
Socket s = new Socket(hostName,portNumber);
where s is the instance of type Socket and hostName,portNumber are the name of the host and port to connect to. But a socket by itself is not very useful without a data input and data output stream. The code segment below sets up a data input and output stream to talk to the socket:
dis= new DataInputStream(s.getInputStream()); dos= new DataOutputStream(new BufferedOutputStream(s.getOutputStream()));
The output stream is created as a buffered output stream. Data will not be written across the socket unless either Java feels that there is enough data to write, or you force a write—using a flush by using something like: dos.flush(); this calls the flush method on the data output stream. On the reading side of the socket, we can simply go into an infinite loop and poll for data from the server, since the listener is running as a separate thread.
Java has most of the same basic data types as C, with a few exceptions. Java has no unsigned integers, but it does have true booleans. To construct the data packet, use a combination of Integers and an array of 120 bytes for the handle and message fields. The data output and input streams have methods for reading and writing integers and bytes. For example, dos.writeInt(1); would write the integer “1” to the data output stream. Conversely, for (int i=0;i<120;i++) dos.writeByte(buffer[i]); (or dos.readByte(buffer[i]) to read) would write the entire buffer to the socket; dos.flush() will make sure that the data is written now and not delayed. It is important to note that we must write or read all of the data (command, channel, handle and message) to or from the server even if all we want to do is change the channel. The server expects this; otherwise it will hang, waiting for all of the bytes to come or go.
One more obstacle remains. How to get the handle and message data into the proper position in the byte array? In the event handler we create string objects for the message and handle, then call the getBytes() method on the string objects. message.getBytes(0,message.length(),buffer,20); will copy message.length() bytes from the string object message starting at position 0 in the string to the byte array buffer starting at position 20. One thing that is missing in my program is error checking. It would be absolutely necessary in a production program to check and recheck to make sure that you don't overflow the buffer by writing more bytes than the buffer can hold.
|Designing Electronics with Linux||May 22, 2013|
|Dynamic DNS—an Object Lesson in Problem Solving||May 21, 2013|
|Using Salt Stack and Vagrant for Drupal Development||May 20, 2013|
|Making Linux and Android Get Along (It's Not as Hard as It Sounds)||May 16, 2013|
|Drupal Is a Framework: Why Everyone Needs to Understand This||May 15, 2013|
|Home, My Backup Data Center||May 13, 2013|
- Designing Electronics with Linux
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Dynamic DNS—an Object Lesson in Problem Solving
- Using Salt Stack and Vagrant for Drupal Development
- New Products
- Build a Skype Server for Your Home Phone System
- Validate an E-Mail Address with PHP, the Right Way
- A Topic for Discussion - Open Source Feature-Richness?
- Why Python?
- Tech Tip: Really Simple HTTP Server with Python
2 hours 3 min ago
- Reply to comment | Linux Journal
2 hours 11 min ago
- Understanding the Linux Kernel
4 hours 25 min ago
6 hours 55 min ago
- Kernel Problem
16 hours 58 min ago
- BASH script to log IPs on public web server
21 hours 25 min ago
1 day 1 hour ago
- Reply to comment | Linux Journal
1 day 1 hour ago
- All the articles you talked
1 day 3 hours ago
- All the articles you talked
1 day 4 hours ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi
It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?