In the past few weeks I have been working on creating a socket server as part of my apprenticeship. Before starting the server I had very little idea about what writing my own server entailed. When I think of a server I visualize a big dark room with giant boxes that have blinky lights and cords all over the place. I never really thought of how a server worked. In this post I have made glossary of sorts to summarize my learnings.
I guess I should start by explaining what a server is. A server manages network resources, it is a program that provides a service to another computer or program. The computer or program on the receiving side is called a client.
So how does the server and client connect?
Well the communication is made through sockets. A socket is a two way connection endpoint. The server has a socket bound to a specific port number. The server waits, listening to the socket for the client to make a service request. In order to make this service request the client will have to know the hostname of the machine that the server is running on and bind to the local port number that the server is offering. Once the server accepts the service request the client and server are able to communicate with each other through this socket.
How is the server and client able to communicate through the socket?
To send data through the socket you will have to get the Output Stream from the socket. To read data from the socket you will have to get the Input Stream from the socket. So in other words, to send data like an HTTP request to the server the client will have to write to the Output Stream for the server to read that request from the Input Stream.
Here is an analogy that was helpful in my understanding the role of sockets:
Server - you
Client - caller
Socket - phone
Bind - assigning a phone number to the phone
Listen - you turn the ringer of the phone on to be notified when you get a call
Accept - when you answer the phone
Read - is you listening to the caller
Write - is you talking into the phone
Close - is when either you or the caller hanging up
Now let’s move on to the client, how do we make a request, and what is HTTP?
HTTP stands for Hypertext Transfer Protocol. It is an application layer protocol for transmitting documents such as HTML, text, video, audio, and images. When I say application layer protocol or HTTP, it is hard to grasp what that exactly means, but it is not that intimidating. A protocol in the computer world is pretty much a set of rules that the computer has to follow. So HTTP is just a set of rules that need to be followed for making these connections.
A HTTP request consists of a request line, zero or more headers, an empty line that separates the the headers and the body, and an optional message body.
It will look something like this:
This request is sent into the Output Stream of the client as bytes to the server. The server then reads the data that came through using the Input Stream, and sends back a response through the servers Output Stream, depending on the content of the request. This response read by the client's Input Stream. And this is what a response message can look like.
Let’s dissect the requests and responses further.
The request line starts with a HTTP request method. In the example above it is the GET method. The method name must be in uppercase for it to be valid. Here are some of the methods I have used for my server:
- GET - retrieves information
- HEAD - same as GET but only gets the header section, without the body
- POST - sends data to the server, e.g: forms, and files
- PUT - sends data to the server, and replace the targeted resource
- PATCH - sends data to the server, but only partially changes the targeted resource
- DELETE - deletes the targeted resource
- OPTIONS - describes what methods you can use to communicate with the server
Next on the request line is the URI the request is addressing. URI is just a fancy word for address. Every page, or file/document you want to reach will have an address. The above image has a URI of “/doc/test.html”.
After the URI you will have to specify the protocol version that the request is following. In the above image the request is using HTTP/1.1 as its protocol. This linked document has all the official details about the protocol.
On the next line comes the headers. Headers are key and value pairs that contain the particulars of the request or the response. There are a few different types of headers. General headers are headers that can be applied to both request and response. Request headers will contain particulars of the request headers. Response headers will contain the particulars of the response. And lastly there are entity headers, which contain details about the entity or body.
Some common headers include:
- Date: Wed, 21 Oct 2015 07:28:00 GMT
- Cache-Control: immutable
- Connection: keep-alive
- Host: developer.mozilla.org
- User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
- Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
- Accept-Language: en-US,en;q=0.5
- Server: Apache
- Location: /index.html
- Age: 24
- Content-Length: 89
- Content-Language: de-DE
- Content-Encoding: gzip
After the headers are specified there is one empty line to separate the headers from the body. The body contains the data that you want to pass on to the server. Not all requests or responses has a body.
The response is structured similar to the request. However the first line, the response line will contain the HTTP version used along with the status code. Response status codes indicate whether a specific HTTP request has been successfully completed. Responses are grouped in five classes: informational responses, successful responses, redirects, client errors, and servers errors. Here are some of the status codes I have used in my server:
Successful response codes:
- 200 OK
- 201 Created
- 202 Accepted
- 204 No Content
- 206 Partial Content
- 302 Found
Client Error codes:
- 401 Unauthorized
- 404 Not Found
- 405 Method Not Allowed
- 418 I’m a teapot
Overall creating a Java server has been one of the most educational projects I have ever attempted. I think this is the kind of project that you could keep working on and you will continue to find things you could do to make it better. In this process I have learnt a lot about communication, design patterns, and Java in general. I hope to continue learning more and maybe have a part 2 to this post.