From 440cfcbe3976e64928c15f45604db77662ccbe6d Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Sun, 5 Feb 2017 12:08:02 +0100 Subject: [PATCH] Refactor + cleanup + lib:shortcode:debug - transmission error (pointer malloc-ed in function ??) [TO FIX] --- client | Bin 12144 -> 17792 bytes client.c | 55 +++------------ client.o | Bin 7688 -> 6112 bytes lib.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- lib.h | 28 +++++--- lib.o | Bin 2680 -> 10664 bytes server | Bin 16536 -> 18096 bytes server.c | 41 +---------- server.o | Bin 8248 -> 6752 bytes 9 files changed, 230 insertions(+), 96 deletions(-) diff --git a/client b/client index 82beefdf88b0aca216c64bee1d6b70510b067ba7..3975bb06775fa62567ef37e75591e62d70829451 100755 GIT binary patch literal 17792 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 literal 12144 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, // ) - /* ( */ server_host->h_length ); - - - /* [3] Send message =========================================================*/ - // calculate server id struct size - sock_len = sizeof(struct sockaddr_in); - - /* (1) Send message to server (identified by ) */ - nb_bytes = sendto( sock, // ) socket - /* ( */ msg, // ) buffer - /* ( */ strlen(msg) + 1, // ) buffer size - /* ( */ 0, // ) flags - /* ( */ (struct sockaddr*) &server_addr, // ) server identifier - /* ( */ sock_len ); // identifier size - + /* (1) Send message to server */ + nb_bytes = xsend(sock, msg, (struct sockaddr*) &server_addr); /* (2) Check if send succesfully */ if( nb_bytes == -1 ){ @@ -88,12 +53,8 @@ int main(int argc, char* argv[]){ /* [4] Wait for response =========================================================*/ - nb_bytes = recvfrom( sock, // ) socket - /* ( */ buffer, // ) receive buffer - /* ( */ BUFSIZE, // ) buffer size - /* ( */ 0, // ) flags - /* ( */ (struct sockaddr*) &server_addr, // ) server identifier - /* ( */ &sock_len ); // identifier size + /* (1) Wait for response */ + nb_bytes = xlisten(sock, (struct sockaddr*) &server_addr, buffer, BUFSIZE); /* (2) Check if received successfully (and consistently) */ if( nb_bytes == -1 ){ @@ -102,7 +63,7 @@ int main(int argc, char* argv[]){ } /* (3) Copy response into var */ - response = (char *) malloc(nb_bytes * sizeof(char)); + response = (char*) malloc(nb_bytes * sizeof(char)); memcpy(response, buffer, nb_bytes); /* (4) log */ diff --git a/client.o b/client.o index 8cb6312046dde2a546ca9548e4bcb2a1e82e667e..d7c42baf0d41ee0e3ea146b82e4cc61efe4bd261 100644 GIT binary patch literal 6112 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 diff --git a/lib.c b/lib.c index f45d077..f2a8f62 100644 --- a/lib.c +++ b/lib.c @@ -1,6 +1,206 @@ #include "lib.h" +int debug(const char* tag, const char* msg){ + + /* (1) Get number of characters to add */ + int diff = DEBUG_LEN - strlen(msg) - strlen(tag) - 3; + + /* (2) print msg */ + printf("[%s] %s", tag, msg); + + /* (3) print missing characters */ + for( ; diff >= 0 ; diff-- ) + printf("."); + + return 1; +} -int createUPDSocket(int port){ return 1; } + + + + +int xbind(const int port){ + + /* [0] Initialization + =========================================================*/ + int xsocket, bound; + static struct sockaddr_in addr; + + + /* [1] Create xsocket + =========================================================*/ + /* (1) Create UPD xsocket */ + xsocket = socket(AF_INET, SOCK_DGRAM, 0); + DEBUG&& debug("xbind", "creating server socket"); + + /* (r2-) Manage error */ + if( xsocket == -1 ){ + DEBUG&& printf("error\n"); + return -1; + } + + DEBUG&& printf("done\n"); + + /* [2] Set xsocket address information + =========================================================*/ + /* (1) Reset values */ + bzero(&addr, sizeof(struct sockaddr_in)); + + /* (2) Set xsocket addr */ + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = htonl(INADDR_ANY); + + + + /* [3] Bind to port + =========================================================*/ + /* (1) Bind and return -1 if error */ + bound = bind(xsocket, (struct sockaddr*)&addr, sizeof(addr)); + DEBUG&& debug("xbind", "binding socket to port"); + + /* (2) Manage error */ + if( bound == -1 ){ + DEBUG&& printf("error\n"); + return -1; + } + + DEBUG&& printf("done\n"); + + + /* [4] Return xsocket + =========================================================*/ + return xsocket; +} + + + + + + +int xconnect(const char* hostname, const int port, struct sockaddr* serv){ + + /* [0] Initialization + =========================================================*/ + int xsocket, bound; + struct hostent *host; // data found by lookup + static struct sockaddr_in* serv_in; + serv_in = (void*) serv; + + + /* [1] Create xsocket + =========================================================*/ + /* (1) Create UPD xsocket */ + xsocket = socket(AF_INET, SOCK_DGRAM, 0); + DEBUG&& debug("xconnect", "creating client socket"); + + /* (r2-) Manage error */ + if( xsocket == -1 ){ + DEBUG&& printf("error\n"); + return -1; + } + + DEBUG&& printf("done\n"); + + + /* [2] Get information by hostname + =========================================================*/ + /* (1) Process */ + host = gethostbyname(hostname); + DEBUG&& debug("xconnect", "fetch info by hostname"); + + /* (2) Manage error */ + if( host == NULL ){ + DEBUG&& printf("error\n"); + return -1; + } + + DEBUG&& printf("found\n"); + + + + /* [3] Set server useful information from fetched info + =========================================================*/ + /* (1) Reset values */ + bzero(serv, sizeof(struct sockaddr_in)); + DEBUG&& debug("xconnect", "building server info"); + + /* (2) Set server info (ipv4, port) */ + serv_in->sin_family = AF_INET; + serv_in->sin_port = htons(port); + + /* (3) Copy server address */ + memcpy( &serv_in->sin_addr.s_addr, host->h_addr, host->h_length); + + DEBUG&& printf("built\n"); + + + // return socket + return xsocket; +} + + + + + + + + +int xlisten(const int xsocket, const struct sockaddr *client, char* buffer, int bufsize){ + + /* [1] Wait for message through xsocket + =========================================================*/ + /* (1) Useful data + memory allocation */ + socklen_t sock_len = sizeof(struct sockaddr_in); + buffer = (char*) malloc( sizeof(char) * bufsize ); + + /* (2) Listen */ + DEBUG&& debug("xlisten", "waiting for data"); + int read = recvfrom(xsocket, buffer, bufsize, 0, (struct sockaddr *) client, &sock_len); + + /* (3) Manage error */ + if( read == -1 ){ + DEBUG&& printf("error\n"); + return -1; + } + + DEBUG&& printf("received\n"); + + + + /* [2] Return number of read characters + =========================================================*/ + return read; +} + + + + + + +int xsend(const int xsocket, char* buffer, struct sockaddr* target){ + + /* [1] Send buffer (message) to target + =========================================================*/ + /* (1) Useful data */ + socklen_t addr_len = sizeof(struct sockaddr_in); + + /* (2) Send data */ + DEBUG&& debug("xsend", "sending data"); + int sent = sendto(xsocket, buffer, strlen(buffer), 0, target, addr_len); + + /* (3) Manage error */ + if( sent == -1 ){ + DEBUG&& printf("error\n"); + return -1; + } + + DEBUG&& printf("sent\n"); + + + /* [2] Return number of sent characters + =========================================================*/ + return sent; +} diff --git a/lib.h b/lib.h index f3fbe9c..2265e30 100644 --- a/lib.h +++ b/lib.h @@ -7,23 +7,31 @@ // debug flags - # define DEBUG 1 + #define DEBUG 0x1 + #define DEBUG_LEN 40 + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + /************************************************ **** Signatures **** ************************************************/ - /* CREATES A UDP SOCKET - * - * @port Port to use (if 0: random) - * - * @return socket Socket descriptor or -1 if error - * - */ - - int createUPDSocket(int port); + int debug(const char* tag, const char* msg); + int xbind(const int port); + int xconnect(const char* hostname, const int port, struct sockaddr* serv); + int xlisten(const int xsocket, const struct sockaddr *client, char* buffer, int bufsize); + int xsend(const int xsocket, char* buffer, struct sockaddr* target); #endif diff --git a/lib.o b/lib.o index 3d9b2d3b8d0f802c369bfac7d872ff9da0c7d86f..78eba4dc1f289a5aff6187f9e1a137fc384b6287 100644 GIT binary patch literal 10664 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 bVN#BNCn{$j*Hk(CP3SO`XVtBAHSPZg3ceTZ literal 2680 zcmbtW&1(}u6n~rTr?DYz)LQBxf}(;uNhF3^sYdHpRkSEQO4%gSG}!Eh-HEh{dJ(~! zf*^u;@gESpcoh66JbLjD@Fu9}d%H8uWZWR=K=!@&d!O_6&1@c?zj`5MS)i5$r=TY( z6yW`EkFQ2-6>^Y;l}k^)Jh}hlJ^9@F=;CuI(vC$zc1FDR$Y^|ucx&XA1}U}micq^} zkb1TOLqo$YPoT@Bbug1l+nL$Sq%}2~od!rT>-3DBnNOcgADUUp5nSE-;_Qr-!zjZL zYnF1Uy;$A>NT*Mw?J*2~6n{|_KvHk1GI~hNm64=iA3iPXdu9TkQRi^07HqU?tR9<< z$1zcu7O7FRst4Q^d}aCEO}~Dd3u#+e_uIU%*$CQBEpSN@7S8eTw(vWJW=k;Au$Es4 zx57p%bVR2F9X}9o@!Cp$u~f<*XJuB*A1jtB#Y*u+-f4@j#}}I1<3X#Aq8rrL7dGcA zPNkf8nt5j}6qv>71is*P;RjAA0^e%_TwGk7&mUf?bv@CIqdJvtB$XbNDy&#$G9wr4zd=7eqU zXa{E2cc&r~PP@1!E1Q&5;aMr~Ht;=Co{^N^oBkG#X!iR1W*V+{Z*D-G>xTW3l+|9S zPVGvM`-Ww5Qtj`hkU8ZQ<6CiXf)ziW7WO0Bg9y1y&0~U;*E7S%cTQ&DEB- z=A$m+-C8Z+cly+B;CfBo@3PVIxN^Z1!0LXx&GCj~9-dH!#~e>6o>&=(udl8JZkx-( z|C7w3KlMcQQ-!NaW_!M*Ot$*kj{;%Q9jz(UJZVtGn*N6nrTO?*{}TF|F)5MCZ??&_ zrK_L5R8{=x>ys?#lLYBpke!-k{DMSl0iR|}QoM__0GB0I#I#*Tg^7{vPw7yUR1wqm z3M!K7e;a>(LHSetbc>nwHxM&pA_R^E)wv{$mT9|+SW^DaGQa8*<)`y*=I_Xus!kN6 z#bu(`3XoLgSM(m@#GC%MJj}=c;{Qnc8)h)qcNz4wDz8FbN`KQ_`J4Sy`&a(YkxA;` zw}k%DSycXdU(K^av9t10d_#h^%=$?-YbW!L1ec}56k_!CGV{|rP0Ig4g7~MbZ<+aj E18H-&RsaA1 diff --git a/server b/server index c7ca09097b07c12073bd9092cced2b7128d26f64..8bcf89c3fd626a37309c2b6c27a7a9cd294e6695 100755 GIT binary patch literal 18096 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 delta 5211 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