TSP: The Transport Sample Protocol



Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

tsp_stream_receiver.c

Go to the documentation of this file.
00001 
00038 #include "tsp_sys_headers.h"
00039 
00040 #include <netdb.h>
00041 #include <netinet/in.h>
00042 #include <netinet/tcp.h>
00043 #include <sys/socket.h>
00044 
00045 #ifndef SHUT_RDWR
00046 #define SHUT_RDWR 2
00047 #endif
00048 
00049 #include "tsp_stream_receiver.h"
00050 
00051 struct TSP_socket_t
00052 {
00053   int socketId;
00054 
00056   int is_stopped;
00057 };
00058 
00059 typedef struct TSP_socket_t TSP_socket_t;
00060 
00061 TSP_stream_receiver_t TSP_stream_receiver_create(const  char* data_address)
00062 {
00063 
00064   int status = 0;
00065   struct hostent* Host_p = NULL;
00066   int OptInt = 0;
00067   int ret = TRUE;
00068   int Len = 0;
00069   char* host;
00070   char* str_port;
00071   unsigned short port;
00072   char* last; 
00074   TSP_socket_t* sock = (TSP_socket_t*)calloc(1, sizeof(TSP_socket_t));
00075   sock->is_stopped = FALSE;
00076   TSP_CHECK_ALLOC(sock, 0);
00077 
00078   
00079   /* Decode the data adresse (get the host name and the port) */
00080   host = strtok_r((char* )data_address, ":", &last);
00081   str_port = strtok_r(NULL, ":", &last);
00082   port = (unsigned short)atoi(str_port);
00083   
00084   STRACE_DEBUG(("Connection Data : Host='%s' port=%u", host, (unsigned int)port));
00085 
00086   /* Init socket */
00087   sock->socketId = socket(AF_INET, SOCK_STREAM, 0);
00088 
00089   if (sock->socketId > 0)
00090     {
00091       /* size of receiver fifo should be half the size of sender fifo for perfomance reason */
00092       OptInt = TSP_DATA_STREAM_SOCKET_FIFO_SIZE / 2;
00093       status = setsockopt(sock->socketId, SOL_SOCKET, SO_RCVBUF, (void * )&OptInt, sizeof(OptInt));
00094       if (status == -1)
00095         {
00096           STRACE_ERROR(("Probleme with set socket size"));
00097 
00098           close(sock->socketId);
00099           free(sock);
00100           return 0;
00101         }
00102 
00103       /* Local address reuse */
00104 
00105       OptInt = 1;
00106       status = setsockopt(sock->socketId, SOL_SOCKET, SO_REUSEADDR,
00107                           (void *) &OptInt, sizeof(OptInt));
00108       if (status == -1)
00109         {
00110           STRACE_ERROR(("pb set local address reuse"));
00111           close(sock->socketId);
00112           free(sock);
00113           return 0;
00114         }
00115 
00116       /* No periodic connection state control */
00117 
00118       OptInt = 0;
00119       status = setsockopt(sock->socketId, SOL_SOCKET, SO_KEEPALIVE,
00120                           (void *) &OptInt, sizeof(OptInt));
00121       if (status == -1)
00122         {
00123           STRACE_ERROR(("pb set periodic state control"));
00124 
00125           close(sock->socketId);
00126           free(sock);
00127           return 0;
00128         }
00129 
00130       /* TCP No delay */
00131       OptInt = 1;
00132       status = setsockopt(sock->socketId, IPPROTO_TCP, TCP_NODELAY, (void *) &OptInt,
00133                           sizeof(OptInt));
00134       if (status == -1)
00135         {
00136           STRACE_ERROR(("pb set TCP no delay"));
00137 
00138           close(sock->socketId);
00139           free(sock);
00140           return 0;
00141         }
00142 
00143       /* Bind to socket : */
00144       /* Get host from the database */
00145       Host_p = gethostbyname(host);
00146       if (Host_p == (struct hostent *) NULL)
00147         {
00148           STRACE_ERROR(("pb get host by name"));
00149 
00150           close(sock->socketId);
00151           free(sock);
00152           return 0;
00153         }
00154 
00155       {
00156         /* we do not use in_addr_t, since it does not work with Solaris,
00157          and anyway, any system typedef this as an int or uint*/
00158         uint32_t InAddr;
00159 
00160         struct sockaddr_in readAddr;
00161 
00162         bcopy((char *) Host_p->h_addr, (char *) &InAddr, Host_p->h_length);
00163         InAddr = ntohl(InAddr);
00164 
00165         bzero((char *) &readAddr, sizeof(struct sockaddr_in));
00166         readAddr.sin_family = AF_INET;
00167 #ifdef _SOCKADDR_LEN
00168         readAddr.sin_len = sizeof(ListenAddr);
00169 #endif
00170         readAddr.sin_addr.s_addr = htonl(InAddr);
00171         readAddr.sin_port = htons(port);
00172     
00173         /* connect to server */
00174         status = connect(sock->socketId, (struct sockaddr*)&readAddr, sizeof(readAddr));
00175       }
00176     
00177       if (status == -1)
00178         {
00179           STRACE_ERROR(("pb connecting to socket"));
00180           close(sock->socketId);
00181           free(sock);
00182           return 0;
00183         }
00184 
00185     }
00186   else
00187     {
00188       free(sock);
00189     }
00190 
00191     
00192   return sock;
00193 }
00194 
00195 void TSP_stream_receiver_prepare_stop(TSP_stream_receiver_t receiver)
00196 {
00197 
00198   TSP_socket_t* sock = (TSP_socket_t*)receiver;
00199 
00200 
00201   STRACE_IO(("-->IN"));
00202   
00203   sock->is_stopped = TRUE;    
00204 
00205   STRACE_IO(("-->OUT"));
00206 
00207 }
00208 
00209 
00210 void TSP_stream_receiver_stop(TSP_stream_receiver_t receiver)
00211 {
00212 
00213   TSP_socket_t* sock = (TSP_socket_t*)receiver;
00214 
00215 
00216   STRACE_IO(("-->IN"));
00217 
00218   sock->is_stopped = TRUE;      
00219   shutdown(sock->socketId, SHUT_RDWR);
00220   close(sock->socketId);
00221 
00222   STRACE_IO(("-->OUT"));
00223 
00224 }
00225 
00226 void TSP_stream_receiver_destroy(TSP_stream_receiver_t receiver)
00227 {
00228 
00229   TSP_socket_t* sock = (TSP_socket_t*)receiver;
00230 
00231   STRACE_IO(("-->IN"));
00232 
00233   free(sock);
00234 
00235   STRACE_IO(("-->OUT"));
00236 
00237 }
00238 
00239 
00240 int TSP_stream_receiver_is_stopped(TSP_stream_receiver_t receiver)
00241 {
00242 
00243   TSP_socket_t* sock = (TSP_socket_t*)receiver;
00244 
00245   return sock->is_stopped;
00246 
00247 }
00248 
00249 int TSP_stream_receiver_receive(TSP_stream_receiver_t receiver, char *buffer, int bufferLen)
00250 {
00251 
00252   int nread;
00253   int Total;
00254   int identSocket  = ((TSP_socket_t*)receiver)->socketId;
00255   
00256   Total = 0;
00257   
00258   if(identSocket > 0)
00259     {
00260       while ( bufferLen > 0)
00261         {
00262           if ( (nread = read(identSocket, &buffer[Total], bufferLen)) < 0)
00263             {
00264               if( errno == EINTR )
00265                 {
00266                   /* The read might have been interrupted by a signal */
00267                   nread = 0;
00268                 }
00269               else 
00270                 {
00271                   
00272                   STRACE_INFO(("read failed"));
00273                   return FALSE;
00274                 }
00275             }else if (nread == 0)
00276               {
00277                 STRACE_INFO(("Received socket EOF"));
00278                 return FALSE;
00279               }
00280           
00281           Total += nread;
00282           bufferLen -= nread;
00283         }
00284     }
00285   return TRUE;
00286 }
Framework Home Page.

Beware !! TSP wave is coming...