From ab7132a03e9be01340c04d228731372ff40ddf16 Mon Sep 17 00:00:00 2001 From: fcolin Date: Tue, 12 Jul 2005 15:53:07 +0000 Subject: suppression du terminateur dans le code socket en vu d'une transmission binaire --- src/ivy.c | 49 ++++++++++++++++++++--------- src/ivysocket.c | 96 ++++++++++++--------------------------------------------- src/ivysocket.h | 18 +++++------ 3 files changed, 61 insertions(+), 102 deletions(-) diff --git a/src/ivy.c b/src/ivy.c index ce9b2e8..ca55b92 100644 --- a/src/ivy.c +++ b/src/ivy.c @@ -362,7 +362,7 @@ static int CheckConnected( IvyClientPtr clnt ) return 0; } -static void Receive( Client client, void *data, char *line ) +static char* Receive( Client client, void *data, char *message, unsigned long len ) { IvyClientPtr clnt; int id; @@ -372,19 +372,27 @@ static void Receive( Client client, void *data, char *line ) char *argv[MAX_MSG_FIELDS]; int kind_of_msg = Bye; IvyBinding bind; + char *ptr_end; - argc = SplitArg( line, MESSAGE_SEPARATOR, argv); + ptr_end = memchr (message, MESSAGE_TERMINATOR, len ); + if ( !ptr_end ) + { + return ptr_end; + } + *ptr_end ='\0'; + + argc = SplitArg( message, MESSAGE_SEPARATOR, argv); kind_of_msg = atoi( argv[MSGTYPE] ); id = atoi( argv[MSGID] ); if ( (argc < 2) ) { - printf("Quitting bad format %s\n", line); + printf("Quitting bad format %s\n", message); MsgSendTo( client, Error, Error, "bad format request expected 'appid type id ...'" ); MsgSendTo( client, Bye, 0, "" ); SocketClose( client ); - return; + return ptr_end; } clnt = (IvyClientPtr)data; switch( kind_of_msg ) @@ -410,7 +418,7 @@ static void Receive( Client client, void *data, char *line ) #ifdef DEBUG printf("Warning: regexp '%s' illegal, removing from %s\n",argv[ARG_0],ApplicationName); #endif //DEBUG - return; + return ptr_end; } bind = IvyBindingCompile( argv[ARG_0] ); if ( bind != NULL ) @@ -503,7 +511,7 @@ static void Receive( Client client, void *data, char *line ) printf("Calling id=%d argc=%d for %s\n", id, argc-ARG_0,rcv->regexp); #endif if ( rcv->callback ) (*rcv->callback)( clnt, rcv->user_data, argc-ARG_0, &argv[ARG_0] ); - return; + return ptr_end; } } printf("Callback Message id=%d not found!!!'\n", id); @@ -541,10 +549,10 @@ static void Receive( Client client, void *data, char *line ) } break; default: - printf("Receive unhandled message %s\n", line); + printf("Receive unhandled message %s\n", message); break; } - + return ptr_end; } static IvyClientPtr SendService( Client client ) @@ -613,7 +621,7 @@ static void *ClientCreate( Client client ) return SendService (client); } -static void BroadcastReceive( Client client, void *data, char *line ) +static char* BroadcastReceive( Client client, void *data, char *message, unsigned long len) { Client app; int err; @@ -626,7 +634,16 @@ static void BroadcastReceive( Client client, void *data, char *line ) char *remotehost = 0; #endif - err = sscanf (line,"%d %hu %s %s\n", &version, &serviceport, appid, appname ); + char *ptr_end; + + ptr_end = memchr (message, '\n', len ); + if ( !ptr_end ) + { + return ptr_end; + } + *ptr_end ='\0'; + + err = sscanf (message,"%d %hu %s %s\n", &version, &serviceport, appid, appname ); if ( err != 4 ) { /* ignore the message */ unsigned short remoteport; @@ -634,7 +651,7 @@ static void BroadcastReceive( Client client, void *data, char *line ) SocketGetRemoteHost (client, &remotehost, &remoteport ); printf (" Bad supervision message, expected 'version port appname appid' from %s:%d\n", remotehost, remoteport); - return; + return ptr_end; } if ( version != VERSION ) { /* ignore the message */ @@ -643,10 +660,11 @@ static void BroadcastReceive( Client client, void *data, char *line ) SocketGetRemoteHost (client, &remotehost, &remoteport ); fprintf (stderr, "Bad Ivy version, expected %d and got %d from %s:%d\n", VERSION, version, remotehost, remoteport); - return; + return ptr_end; } - /* check if we received our own message. SHOULD ALSO TEST THE HOST */ - if (serviceport == ApplicationPort) return; + /* check if we received our own message */ + if (strcmp( appid,applicationUniqueId )== 0) + return ptr_end; #ifdef DEBUG SocketGetRemoteHost (client, &remotehost, &remoteport ); @@ -654,12 +672,13 @@ static void BroadcastReceive( Client client, void *data, char *line ) #endif //DEBUG /* connect to the service and send the regexp */ - app = SocketConnectAddr(SocketGetRemoteAddr(client), serviceport, 0, Receive, MESSAGE_TERMINATOR, ClientDelete ); + app = SocketConnectAddr(SocketGetRemoteAddr(client), serviceport, 0, Receive, ClientDelete ); if (app) { IvyClientPtr clnt; clnt = SendService( app ); SocketSetData( app, clnt); } + return ptr_end; } void IvyInit (const char *appname, const char *ready, diff --git a/src/ivysocket.c b/src/ivysocket.c index d777350..da5e7a8 100644 --- a/src/ivysocket.c +++ b/src/ivysocket.c @@ -48,10 +48,9 @@ struct _server { HANDLE fd; Channel channel; unsigned short port; - void *(*create)(Client client); - void (*handle_delete)(Client client, void *data); + SocketCreate create; + SocketDelete handle_delete; SocketInterpretation interpretation; - char terminator; /* character delimiter of the client message */ }; struct _client { @@ -61,8 +60,7 @@ struct _client { unsigned short port; struct sockaddr_in from; SocketInterpretation interpretation; - void (*handle_delete)(Client client, void *data); - char terminator; /* character delimiter of the message */ + SocketDelete handle_delete; long buffer_size; char *buffer; /* dynamicaly reallocated */ char *ptr; @@ -143,7 +141,7 @@ static void HandleSocket (Channel channel, HANDLE fd, void *data) { Client client = (Client)data; char *ptr; - char *ptr_nl; + char *ptr_end; long nb_to_read = 0; long nb; socklen_t len; @@ -175,16 +173,18 @@ static void HandleSocket (Channel channel, HANDLE fd, void *data) } client->ptr += nb; ptr = client->buffer; - while ((ptr_nl = memchr (ptr, client->terminator, client->ptr - ptr ))) + if (! client->interpretation ) + { + client->ptr = client->buffer; + fprintf (stderr,"Socket No interpretation function ??? skipping data\n"); + return; + } + while ((ptr_end = (*client->interpretation) (client, client->data, ptr, client->ptr - ptr ))) { - *ptr_nl ='\0'; - if (client->interpretation ) - (*client->interpretation) (client, client->data, ptr ); - else fprintf (stderr,"Socket No interpretation function ???\n"); - ptr = ++ptr_nl; + ptr = ++ptr_end; } if (ptr < client->ptr ) - { /* recopie ligne incomplete au debut du buffer */ + { /* recopie message incomplet au debut du buffer */ len = client->ptr - ptr; memcpy (client->buffer, ptr, len ); client->ptr = client->buffer + len; @@ -228,7 +228,6 @@ static void HandleServer(Channel channel, HANDLE fd, void *data) fprintf(stderr,"HandleSocket Buffer Memory Alloc Error\n"); exit(0); } - client->terminator = server->terminator; client->from = remote2; client->fd = ns; client->channel = IvyChannelOpen (ns, client, DeleteSocket, HandleSocket ); @@ -239,9 +238,9 @@ static void HandleServer(Channel channel, HANDLE fd, void *data) } Server SocketServer(unsigned short port, - void*(*create)(Client client), - void(*handle_delete)(Client client, void *data), - void(*interpretation) (Client client, void *data, char *ligne)) + SocketCreate create, + SocketDelete handle_delete, + SocketInterpretation interpretation ) { Server server; HANDLE fd; @@ -427,8 +426,7 @@ Ouverture d'un canal TCP/IP en mode client Client SocketConnect (char * host, unsigned short port, void *data, SocketInterpretation interpretation, - char terminator, - void (*handle_delete)(Client client, void *data) + SocketDelete handle_delete ) { struct hostent *rhost; @@ -437,14 +435,13 @@ Client SocketConnect (char * host, unsigned short port, fprintf(stderr, "Erreur %s Calculateur inconnu !\n",host); return NULL; } - return SocketConnectAddr ((struct in_addr*)(rhost->h_addr), port, data, interpretation, terminator, handle_delete); + return SocketConnectAddr ((struct in_addr*)(rhost->h_addr), port, data, interpretation, handle_delete); } Client SocketConnectAddr (struct in_addr * addr, unsigned short port, void *data, SocketInterpretation interpretation, - char terminator, - void (*handle_delete)(Client client, void *data) + SocketDelete handle_delete ) { HANDLE handle; @@ -479,7 +476,6 @@ Client SocketConnectAddr (struct in_addr * addr, unsigned short port, fprintf(stderr,"HandleSocket Buffer Memory Alloc Error\n"); exit(0); } - client->terminator = terminator; client->fd = handle; client->channel = IvyChannelOpen (handle, client, DeleteSocket, HandleSocket ); client->interpretation = interpretation; @@ -491,59 +487,6 @@ Client SocketConnectAddr (struct in_addr * addr, unsigned short port, client->from.sin_port = htons (port); return client; } -// TODO factoriser avec HandleRead !!!! -int SocketWaitForReply (Client client, char *buffer, int size, int delai) -{ - fd_set rdset; - struct timeval timeout; - struct timeval *timeoutptr = &timeout; - int ready; - char *ptr; - char *ptr_nl; - long nb_to_read = 0; - long nb; - HANDLE fd; - - fd = client->fd; - ptr = buffer; - timeout.tv_sec = delai; - timeout.tv_usec = 0; - do { - /* limitation taille buffer */ - nb_to_read = size - (ptr - buffer ); - if (nb_to_read == 0 ) - { - fprintf(stderr, "Erreur message trop long sans LF\n"); - ptr = buffer; - return -1; - } - FD_ZERO (&rdset ); - FD_SET (fd, &rdset ); - ready = select(fd+1, &rdset, 0, 0, timeoutptr); - if (ready < 0 ) - { - perror("select"); - return -1; - } - if (ready == 0 ) - { - return -2; - } - if ((nb = recv (fd , ptr, nb_to_read, 0 )) < 0) - { - perror(" Read Socket "); - return -1; - } - if (nb == 0 ) - return 0; - - ptr += nb; - *ptr = '\0'; - ptr_nl = strchr (buffer, client->terminator ); - } while (!ptr_nl ); - *ptr_nl = '\0'; - return (ptr_nl - buffer); -} /* Socket UDP */ @@ -608,7 +551,6 @@ Client SocketBroadcastCreate ( fprintf(stderr,"HandleSocket Buffer Memory Alloc Error\n"); exit(0); } - client->terminator = '\n'; client->fd = handle; client->channel = IvyChannelOpen (handle, client, DeleteSocket, HandleSocket ); client->interpretation = interpretation; diff --git a/src/ivysocket.h b/src/ivysocket.h index b57a632..9bfb17f 100644 --- a/src/ivysocket.h +++ b/src/ivysocket.h @@ -53,13 +53,15 @@ extern int make_message_var(char ** buffer, int *size, int offset, const char * /* Forward def */ typedef struct _client *Client; -typedef void (*SocketInterpretation) (Client client, void *data, char *ligne); +typedef char* (*SocketInterpretation) (Client client, void *data, char *ligne, unsigned long len); +typedef void* (*SocketCreate) (Client client); +typedef void (*SocketDelete) (Client client, void *data); /* Server Part */ typedef struct _server *Server; extern Server SocketServer(unsigned short port, - void*(*create)(Client client), - void(*handle_delete)(Client client, void *data), + SocketCreate create, + SocketDelete handle_delete, SocketInterpretation interpretation); extern unsigned short SocketServerGetPort( Server server ); extern void SocketServerClose( Server server ); @@ -76,17 +78,13 @@ extern void SocketBroadcast( char *fmt, ... ); extern Client SocketConnect( char * host, unsigned short port, void *data, SocketInterpretation interpretation, - char terminator, - void (*handle_delete)(Client client, void *data) - ); + SocketDelete handle_delete + ); extern Client SocketConnectAddr( struct in_addr * addr, unsigned short port, void *data, SocketInterpretation interpretation, - char terminator, - void (*handle_delete)(Client client, void *data) + SocketDelete handle_delete ); -extern int SocketWaitForReply( Client client, char *buffer, int size, int delai); - /* Socket UDP */ /* Creation d'une socket en mode non connecte */ /* et ecoute des messages */ -- cgit v1.1