Sockets - The lqNetDog mini-lib for socket connections
Posted 01-22-2013 at 06:40 AM by rainbowsally
Updated 01-22-2013 at 10:52 AM by rainbowsally (moved some includes)
Updated 01-22-2013 at 10:52 AM by rainbowsally (moved some includes)
Tags computer mad science, mc2, simple c, sockets
[Bad logic level in netdog_request() presumably fixed. -rs]
Sockets - The NetDog mini-lib for socket connections
Today's feature is:
Complicating this stuff is easy. Simplifying it is the hard part.
The non-blocking setup here simplifies coding for a gui which needs to constantly be receiving events, which is what we'll be using it for, but for those with other purposes in mind, this MIGHT be the key to hacking socket security (i.e., the DOCUMENTATION) and getting your own projects rolling. ;-)
The option to the non-blocking setup for a gui application is to create threads and a mutex, which can obscure the simplicity of the basic concepts. So here's netdog version 1.0.
The functions are divided up into 'ans' as in "answer" and 'orig' as in "originate" blocks. The functions are not enforced and there's no error checking so check the header file to make sure you're using the right functions for your listener (ans) or your connector (orig).
To run the demo app (which has a very long loop timeout so that you can set DEBUG to watch the run-states change, if you want to) first do something like
and then in xterm
because the answer side has to be "listening" for the originator of the connection request to connect, right?
Lots of confusing words, but if you think about it, you can't talk to someone on a phone if nobody's there to ans-wer it (the listener), and it's you that "originates" the call (connects) because they don't know who's calling or when a call might come in.
So run 'ans' first.
Then with the commandline above, your first terminal should be able to run the second app.
And type in some stuff. 'bye' ends the connection side. 'shutdown' ends BOTH sides, after which (on my system) there is a 60 second timeout before 'ans' can run again, with the error indicating that the address and port are already in use.
[define DEBUG = 1 in the sources if you want to watch the 'run' loop states change if you're interested in the nuts and bolts of running a gui in the same thread as the sockets.]
Here's ans.
file: ans.cpp
purpose: source file
And here's orig
file: orig.cpp
purpose: source file
And here's a self extractor for the netdog includes. Coulda been a lib, but then you couldn't mess with the code as easily if you want to experiment with it.
[Had a bad logic level in netdog_request() now presumably fixed. -rs]
file: netdog-v1.0.sfxz
purpose: utility (executable)
Here's the mc2 definitions, from which you can probably figure out how to generate your own makefile if you're good at that kind of stuff. Or just run 'mc2 -init' if you have the libLQ d/load here http://www.linuxquestions.org/questi...support-34783/
file: mc2.def
purpose: source file
- The Computer Mad Science Team
:-)
Sockets - The NetDog mini-lib for socket connections
Today's feature is:
- NetDog. :-)
- A simple non-blocking ans (listen) and orig (connect) example.
- Minor bundling of socket functions to greatly simplify a successful connection.
Complicating this stuff is easy. Simplifying it is the hard part.
The non-blocking setup here simplifies coding for a gui which needs to constantly be receiving events, which is what we'll be using it for, but for those with other purposes in mind, this MIGHT be the key to hacking socket security (i.e., the DOCUMENTATION) and getting your own projects rolling. ;-)
The option to the non-blocking setup for a gui application is to create threads and a mutex, which can obscure the simplicity of the basic concepts. So here's netdog version 1.0.
The functions are divided up into 'ans' as in "answer" and 'orig' as in "originate" blocks. The functions are not enforced and there's no error checking so check the header file to make sure you're using the right functions for your listener (ans) or your connector (orig).
To run the demo app (which has a very long loop timeout so that you can set DEBUG to watch the run-states change, if you want to) first do something like
Code:
xterm & # with the ampersand
Code:
ans
Lots of confusing words, but if you think about it, you can't talk to someone on a phone if nobody's there to ans-wer it (the listener), and it's you that "originates" the call (connects) because they don't know who's calling or when a call might come in.
So run 'ans' first.
Then with the commandline above, your first terminal should be able to run the second app.
Code:
orig
[define DEBUG = 1 in the sources if you want to watch the 'run' loop states change if you're interested in the nuts and bolts of running a gui in the same thread as the sockets.]
Here's ans.
file: ans.cpp
purpose: source file
Code:
/* server_v4.cpp * by Rainbow Sally Copyright (c) 2013 Rainbow Sally, GPL 3+ */ // Demonstrate IPv4 read / write functions for sockets programming #include <stdio.h> #include <errno.h> #include <resolv.h> #include <sys/socket.h> #include <arpa/inet.h> #include <ctype.h> #include <stdarg.h> #include <ctype.h> // isdigit() #include <stdlib.h> // abort(), exit(), atoi() #include <string.h> // strcmp(), memset() #include <arpa/inet.h> // inet_addr, etc. #include <unistd.h> // close() #include <signal.h> // EADDRINUSE #ifndef streq #define streq(a, b) (strcmp(a, b) == 0) #endif void dbg(){} #include "netdog-v1.0/netdog.h" #include "netdog-v1.0/netdog.cpp" void panic(const char* msg, ...) { va_list ap; va_start(ap, msg); vprintf(msg, ap); va_end(ap); abort(); } static bool show_listener; static netdog_t* my_netdog; void run(); int main(int count, char *strings[]) { dbg(); bool ok; int portnum; const char* port_str = "9999"; // simulates user input const char* addr_str = "127.0.0.1"; // localhost if(!sscanf(port_str, "%d", &portnum)) panic("Can't conver portnum\n"); printf( "Using address '%s', port %s\n" "Waits for connection then echos string typed in client to\n" "stdout and sends the same string back.\n" "Press Ctrl-C to exit\n", addr_str, port_str ); netdog_t* pobj; pobj = netdog_new(addr_str, portnum, 100); my_netdog = pobj; // for runner ok = netdog_createListener(pobj); if(!ok) { printf("Couldn't createListener().\n"); if(errno == EADDRINUSE /*98*/) { printf("*** May be in 60 second OS timeout, try again later\n"); } usleep(250000); exit(1); } show_listener = true; // init run(); } typedef enum { RUN_INIT, RUN_SHOW_LISTEN, RUN_ACCEPT, RUN_SHOW_CONN, RUN_RECEIVE, RUN_SEND, RUN_CLOSE, RUN_SHUTDOWN, RUN_NU }run_states; #if DEBUG /* set this = 1 to watch states change */ const char* state_names[] = { "RUN_INIT", "RUN_SHOW_LISTEN", "RUN_ACCEPT", "RUN_SHOW_CONN", "RUN_RECEIVE", "RUN_SEND", "RUN_CLOSE", "RUN_SHUTDOWN", 0 }; #endif void run() { netdog_t* pobj = my_netdog; bool ok; // outer loop is continuous int loop_state = 0; bool shuttingdown = false; bool closing = false; for(;;) { usleep(250000); // simulate ui timeout (actually 20 ms) #if DEBUG printf("-- %s --\n", state_names[loop_state]); #endif switch(loop_state) { case RUN_INIT: // init shuttingdown = false; closing = false; loop_state = RUN_SHOW_LISTEN; break; case RUN_SHOW_LISTEN: printf("Listening..\n"); loop_state = RUN_ACCEPT; break; case RUN_ACCEPT: // accept // when using SOCK_NONBLOCK we need to verify that the connection was there // and skip back to the loop for a timeout. ok = netdog_accept(pobj); if(ok) loop_state = RUN_SHOW_CONN; // else try again break; case RUN_SHOW_CONN: // display connection // Here's ntop() Network to Presentation format for displaying the address fprintf(stderr, "Connected: %s port=%d, client id = %d\n", inet_ntop(AF_INET, &pobj->addr.sin_addr, pobj->indata, pobj->datamax), ntohs(pobj->addr.sin_port), pobj->rx_fd ); loop_state = RUN_RECEIVE; break; case RUN_RECEIVE: // receive // receive and echo back netdog_receive(pobj); // need better way to tell if the connection // is broken in terminal. gui = ok, just // set closing = true and loop_state = 6. if(pobj->nbytes <= 0) break; // repeat if(streq(pobj->indata, "shutdown\n")) shuttingdown = true; else if(streq(pobj->indata, "bye\n")) closing = true; // in either case... loop_state = RUN_SEND; break; case RUN_SEND: // send netdog_send(pobj, pobj->indata, pobj->datamax); printf("server echoing: %s\n", pobj->outdata); if(closing) loop_state = RUN_CLOSE; else if(shuttingdown) loop_state = RUN_SHUTDOWN; else loop_state = RUN_RECEIVE; // again break; case RUN_CLOSE: // close | shutdown fprintf(stderr, "Closing client %d\n", pobj->rx_fd); netdog_close(pobj); if(shuttingdown) loop_state = RUN_SHUTDOWN; else // show_listener = true; loop_state = RUN_SHOW_LISTEN; // show listener break; case RUN_SHUTDOWN: // close server // TODO: how do we un-bind so we don't have to do this lengthy timeout? netdog_delete(&pobj); fprintf(stderr, "Notice:\n It takes the OS a full 60 seconds to timeout after shutdown\n so this address and port can't be used again for about a minute.\n"); // timeout and uninit return; }// switch loop_state } // for(;;) }
file: orig.cpp
purpose: source file
Code:
/* client_v4.cpp * by Rainbow Sally Copyright (c) 2013 Rainbow Sally, GPL 3+ */ // Demonstrate IPv4 read / write functions for sockets programming #include <stdio.h> #include <errno.h> #include <resolv.h> #include <sys/socket.h> #include <arpa/inet.h> #include <ctype.h> #include <stdarg.h> #include <ctype.h> // isdigit() #include <stdlib.h> // abort(), exit(), atoi() #include <string.h> // strcmp(), memset() #include <unistd.h> // close() #ifndef streq #define streq(a, b) (strcmp(a, b) == 0) #endif void dbg(){} #include "netdog-v1.0/netdog.h" #include "netdog-v1.0/netdog.cpp" void panic(const char* msg, ...) { va_list ap; va_start(ap, msg); vprintf(msg, ap); va_end(ap); abort(); } typedef enum { RUN_INIT, RUN_GET_INPUT, RUN_SEND, RUN_RECEIVE, RUN_CLOSE_CONN, RUN_SHUTDOWN, RUN_DELETE, RUN_EXIT, RUN_NU }run_states; #if DEBUG /* set DEBUG to 1 to watch states change */ const char* state_names[] = { "RUN_INIT", "RUN_GET_INPUT", "RUN_SEND", "RUN_RECEIVE", "RUN_CLOSE_CONN", "RUN_SHUTDOWN", "RUN_DELETE", "RUN_EXIT", 0 }; #endif // MSG_OOB // MSG_PEEK // MSG_DONTROUTE #define MSG_FLAGS 0 /* default */ extern "C" { // noop } int main(int argc, char **argv) { dbg(); bool ok; const char* addr_str = "127.0.0.1"; const char* port_str = "9999"; int portnum; printf( "Using address '%s', port %s\n" "Type text to send to server, 'bye' to end\n" , addr_str, port_str ); if(!sscanf(port_str, "%d", &portnum)) panic("Can't convert portnum\n"); netdog_t* pobj; pobj = netdog_new(addr_str, portnum, 100); // struct sockaddr_in addr; // no listener for originator, just 'request' a connection. ok = netdog_request(pobj); // bool shuttingdown = false; int loop_state = 0; bool shuttingdown = false; bool closing = false; for(;;) { usleep(250000); // simulate ui timeout (actually 20 ms) // if window not visible, loop_state = 7; #if DEBUG printf("-- %s --\n", state_names[loop_state]); #endif switch(loop_state) { case RUN_INIT: // init shuttingdown = false; closing = false; loop_state = RUN_GET_INPUT; break; case RUN_GET_INPUT: // get user input fgets(pobj->indata, pobj->datamax, stdin); loop_state = RUN_SEND; break; case RUN_SEND: // send/shutdown netdog_send(pobj, pobj->indata, pobj->datamax); if(streq(pobj->indata, "shutdown\n")) shuttingdown = true; loop_state = RUN_RECEIVE; break; case RUN_RECEIVE: // receive netdog_receive(pobj); printf("client recieved echo: %s", pobj->indata); if(streq(pobj->indata, "bye\n")) loop_state = RUN_CLOSE_CONN; else if (shuttingdown) loop_state = RUN_SHUTDOWN; else loop_state = RUN_GET_INPUT; // get input break; case RUN_CLOSE_CONN: // close connection netdog_close(pobj); loop_state = RUN_DELETE; break; case RUN_SHUTDOWN: // shut down loop_state = RUN_DELETE; break; case RUN_DELETE: netdog_delete(&pobj); loop_state = RUN_EXIT; case RUN_EXIT: // uninit, close window or whatever return 0; ; } // switch loop_state } // for(;;) return 0; }
[Had a bad logic level in netdog_request() now presumably fixed. -rs]
file: netdog-v1.0.sfxz
purpose: utility (executable)
Code:
#!/bin/sh # base64 self extractor # file: netdog-v1.0 filename=netdog-v1.0 # don't allow user to click on the file if ! tty >/dev/null; then xmessage -center " $(basename $0) must be run in a terminal " exit fi # create and/or clear out tmp dir mkdir -p $HOME/tmp/sfxz rm -rf $HOME/tmp/sfxz/* base64 -d << _BEOF >$HOME/tmp/sfxz/$filename.xz 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 oAEA2uqDmrHEZ/sCAAAAAARZWg== _BEOF (cd $HOME/tmp/sfxz && tar -xaf netdog-v1.0.xz) rm -f $HOME/tmp/sfxz/netdog-v1.0.xz cat << _BEOF > $HOME/tmp/sfxz/post-extract #!/bin/sh is_yes() # returns OK if first char is Y or y { local key=`echo $1 | cut -b1 | sed 's/y/Y/; /Y/!d'` [ "$key" == 'Y' ] && return 0 # true return 1 # false } if [ -e netdog-v1.0 ]; then printf " Overwrite existing file(s)? [N/y]:" read key if ! is_yes $key ;then echo "Aborting.." exit 0 fi fi mv $HOME/tmp/sfxz/netdog-v1.0 . _BEOF sh $HOME/tmp/sfxz/post-extract rm -rf $HOME/tmp/sfxz/* rmdir $HOME/tmp/sfxz 2>/dev/null || true rmdir $HOME/tmp 2>/dev/null || true
Here's the mc2 definitions, from which you can probably figure out how to generate your own makefile if you're good at that kind of stuff. Or just run 'mc2 -init' if you have the libLQ d/load here http://www.linuxquestions.org/questi...support-34783/
file: mc2.def
purpose: source file
Code:
# mc2.def template created with Makefile Creator 'mc2' ## sandbox path and other new variables PREFIX = $(HOME)/usr32 BUILDDIR := $(PWD) # output name override OUTNAME = MULTI SRCDIR = . OBJDIR = o BINDIR = . # compile function overrides COMPILE = g++ -m32 -c -o # COMPILE <output_file> ... # CFLAGS = -Wall -g3 # debug CFLAGS = -Wall -O2 # optimized INCLUDE = -I $(SRCDIR) -I$(PREFIX)/include -I /usr/include # link function overrides LINK = g++ -m32 -o # LINK <output_file> ... LDFLAGS = LIB = -L/usr/lib -L$(PREFIX)/lib semiclean: @rm -f $(OBJ) @rm -f *~ */*~ */*/*~ */*/*/*~ strip: @strip $(MAIN) @make semiclean clean: @rm -f $(MAIN) @rm -f $(OBJ) @rm -f *.kdevelop.pcs *.kdevses @rm -f *~ */*~ */*/*~ */*/*/*~ force: # used to force execution
:-)
Total Comments 0