Mastering Algorithms With C - Kyle Loudon [168]
The send_comp function sends data by first compressing it and then calling the standard socket function send. To send the data, send_comp requires four arguments: s is a socket descriptor for which a connection has already been established, data is the buffer of data to send, size is the size of the data, and flags is the normal flags argument passed to send. To begin the sending process, we compress the data in data by calling huffman_compress. Next, we send the size of the compressed data, as returned by huffman_compress, so that space can be allocated on the receiving end. This is part of a simple protocol we establish with the receiver. Last, we send the compressed data itself and then free it as the interface to huffman_compress suggests.
The recv_comp function uses the standard socket function recv to receive data sent by send_comp. To receive the data, recv_comp requires four arguments: s is a socket descriptor for which a connection has already been established, data is a pointer that recv_comp will set to the uncompressed data, size is the size of the data as set by recv_comp on return, and flags is the normal flags argument passed to recv. To begin the receiving process, we receive the size of the data and allocate a buffer. Next, we receive the compressed data and call huffman_uncompress to uncompress it. Since huffman_uncompress dynamically allocates space for the uncompressed data using malloc, and recv_comp returns this pointer, it is the responsibility of the caller of recv_comp to call free when the data is no longer needed. Last, we free the buffer we allocated to receive the data.
The runtime complexities of send_comp and recv_comp are both O (n), where n is the number of symbols sent or received. These complexities are both O (n) because the two functions call huffman_compress and huffman_uncompress respectively, which are both O (n) operations.
Example 14.4. Implementation of Functions for Optimized Networking
/*****************************************************************************
* *
* ------------------------------ transfer.c ------------------------------ *
* *
*****************************************************************************/
#include #include #include "compress.h" #include "transfer.h" /***************************************************************************** * * * ------------------------------- send_comp ------------------------------ * * * *****************************************************************************/ int send_comp(int s, const unsigned char *data, int size, int flags) { unsigned char *compressed; int size_comp; /***************************************************************************** * * * Compress the data. * * * *****************************************************************************/ if ((size_comp = huffman_compress(data, &compressed, size)) < 0) return -1; /***************************************************************************** * * * Send the compressed data preceded by its size. * * * *****************************************************************************/ if (send(s, (char *)&size_comp, sizeof(int), flags) != sizeof(int)) return -1; if (send(s, (char *)compressed, size_comp, flags) != size_comp) return -1; /***************************************************************************** * * * Free the buffer of compressed data. * * * *****************************************************************************/