- Compression-service
This programm is a small compreesion service. This service consumes data in ASCII format over a TCP socket and return a compressed version of that data.
1.1. Messaging Format
All messages that flow over the socket share a common header that consists
of three fixed width integer fields in the following order:
• A 32 bit wide magic value which is always equal to 0x53545259.
• A 16 bit payload length
• A 16 bit request code / status code
The header may or may not be followed by a payload depending on the message type.
Lastly, all fields are in network byte order.
1.2. Requests
The compression service should support the following request types (request code noted in parenthesis):
• “Ping” (RC: 1)
– Serves as a means to check that the service is operating normally.
• “Get Stats” (RC: 2)
– Retrieves various internal statistics of the service.
• “Reset Stats” (RC: 3)
– Resets the internal statistics to their appropriate default values.
• “Compress” (RC: 4)
– Requests that some data be compressed using a particular compression scheme.
All other request codes should be considered invalid.
1.3 Compression Algorithm
a => a
aa => aa
aaa => 3a
aaaaabbb => 5a3b
aaaaabbbbbbaaabb => 5a6b3abb
abcdefg => abcdefg
- Project developed
The project is written in C++11, developed on Mac OS X 10.13.3, BuildVersion - 17D47. Apple LLVM version 9.0.0 (clang-900.0.39.2). I used library boost (1.68) for work with network. clang++ -Wall -Wextra -Werror -std=c++11 -lboost_system
2.1. How to install boost library 2.1.1. Write this command in terminal "brew install boost"; 2.1.2. Then replace in serverDir/Makefile lines 17 and 18 "/Users/ariabyi/.brew/Cellar/boost/1.68" on address which you will get after command in terminal "brew link boost"; 2.1.3. Do the same with clientDir/Makefile.
- Description of my code
3.1. Client
3.1.1. Usage: ./client host port requestCode ;
3.1.2. Check arguments ;
3.1.3. Create io_service object, for represents program's link to the operating system's I/O services ;
3.1.4. Create object of I/O for perform I/O operations (socket) ;
3.1.5. Create object resolver for performs resolution of a query to a list of entries ;
3.1.6. Connect endpoint and socket ;
3.1.7. Work with server
3.1.7.1. Initialize of header, if we get request code 4 (COMPRESS), we will set in header.length
length of message, what we get ;
3.1.7.2. Send header, and if rq == 4, send message also (only after header) ;
3.1.8. Wait for response of server ;
3.1.9. Get header
3.1.9.1. If we had rq == 1 (PING), we do nothing ;
3.1.9.2. If we had rq == 2 (GET STATS), we get structure of stats ;
3.1.9.3. If we had rq == 3 (RESET STATS), we do nothing ;
3.1.9.4. If we had rq == 4 (COMPRESS), we get compressed message.
3.1.10. Close socket.
3.2. Server
3.2.1. Usage: ./server port ;
3.2.2. Check arguments ;
3.2.3. Create io_service object, for represents program's link to the operating system's I/O services ;
3.2.4. Create object acceptor for accepting new socket connections ;
3.2.5. Accept new connection ;
3.2.6. Separates the thread of execution from the thread object, allowing execution to continue independently ;
3.2.7. When we get connection , get and check header
3.2.7.1. If header.magicValue != our magic value, we give an error WRONGMAGICVALUE_RQ (33) ;
3.2.7.2. If (header <= 0 || header.length > BUFFER_SIZE (32768)), we give an error WRONGLENGHT_RQ (2) ;
3.2.7.3. If (header.requestCode < 1 || header.requestCode > 4), we give an error WRONGREQUESCODE_RQ (3) ;
3.2.8. Work regarding requests
3.2.8.1. If rq == 1 (PING), we send header and header.requestCode = OK (0), and also header.length = 0;
3.2.8.2. If rq == 2 (GET STATS), we send structure of stats
(after header, where header.requestCode = OK (0), and also header.length = 0);
3.2.8.3. If rq == 3 (RESET STATS), we annul stats, and send header
(where header.requestCode = OK (0), and also header.length = 0);
3.2.8.4. If rq == 4 (COMPRESS), we compress message, and send it back to client
(after header, where header.requestCode = OK (0), and also header.length = (length of our compressed message)) ;
3.2.9. Close socket ;
3.2.10. Waiting for the next connection ...
Also everywhere I am looking for the correct execution of functions.
- Features of implementation
When a client requests "Get Statistics", the server returns a "Total Bytes Sent" (without including those statistics that have just been sent).
-
Libraries I used Boost because there are many libraries that tried to solve problem of writing portable networking code in C++, but Boost.asio is the best implementation among existing. On the base of Boost.Asio some number of libraries and applications were already implemented, and development of some new is in progress. So in future, i could easily work with my old projects, and I will not need to rework projects due to obsolete libraries.
-
Install
NAME - name of directory, in which you want to put all extracted files.
$ mkdir NAME && tar -xv --lzma -f compressionHomework.tar.xz -C NAME && cd NAME
- Server responses
0 - OK
1 - Unknown ERROR
2 - Message Too Large
3 - Wrong Request Code
33 - Wrong Magic Number
34 - Message contains numbers
35 - Message contains capital characters
36 - Message contains bad characters
37 - Empty string ("\0")