LinuxQuestions.org
LinuxAnswers - the LQ Linux tutorial section.
Go Back   LinuxQuestions.org > Blogs > rainbowsally
User Name
Password

Notices

Rate this Entry

Sockets - The Black Box

Posted 01-23-2013 at 09:44 AM by rainbowsally

Today's feature:
  • A simple sockets debugging exercise.

Relax. It actually IS simple. You'll see.

You probably wouldn't be reading this if you didn't know how hard it is to find decent, simple example code.

Me too! And so there have been a few missteps in the previous entries (though they are adequate as demos), but it's all starting to shape up.

Yuh know, all I personally needed was a way to communicate between application so I could do stuff like sending commands to a plotting window. I passed that mark quite a while back.

But this sockets stuff, while it sidesteps some of the problems with pipes and fifos, was such a confounding rats nest of misinformation and bad code that well.... I figured I'd take a whack at it for others that might also just want a simple way for two apps to communicate.

Not that we here at the Mad Science Dept. are immune from writing bug infested code. ;-)

As a matter of fact this sfxz contains netdog-v1.2 which addresses a couple of our own bogies.

But we're well over the hump now. Watch how easily we cab set these sockets up for this test.

And let's see for ourselves what one of these hidden quirks that throws us off the trail is right now.

You don't need libLQ or the gui code, just netdog for this. We'll include the new version/release with the bug fixes mentioned above.

Here's the ans(wer) side of the socket.

file: src/ans.cpp
purpose: source file
Code:
// ans.cpp -- skeleton created by new.main

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <unistd.h> // close() needed by netdog.cpp
#include "../netdog-v1.2/netdog.h"
#include "../netdog-v1.2/netdog.cpp"

void dbg(){} // for a non-moving breakpoint

int main(int argc, char** argv)
{
  dbg();
  // the usual localhost port so other netdog experiments can play too!
  printf("Listening: address '127.0.0.1', port 9999\n");
  printf("Ctrl-C to exit\n");
  
  // here's where the 'gotcha' starts.  Buffer size is 100. Not a 
  // problem... yet.  See notes in orig.cpp
  netdog_t* pobj = netdog_new("127.0.0.1", 9999, 100);
  pobj->sock_flags &= ~SOCK_NONBLOCK;
  
  // by default we poll the connection, using NON_BLOCKING for a gui 
  // to run in the same thread and same loop. We want to override 
  // this for a terminal app.
  
  netdog_createListener(pobj);
  printf("Created listener for the connection\n");
  netdog_accept(pobj);
  printf("Accepted (created) new connection\n");
  for(;;)
  {
    netdog_receive(pobj);
    printf("received: %d bytes\n", pobj->nbytes);
    netdog_send(pobj, pobj->indata, pobj->datamax);
    printf("sent: %s\n", pobj->outdata);
    // Up in one of those lines is the listener/server side of the "gotcha".    
  }
  return 0;
}
Simple enough, right? But you do need to create an additional 'listener' for the answer side of a socket. This is because the 'ans'wer side has two fd's.


file: src/orig.cpp
purpose: source file
Code:
// ans.cpp -- skeleton created by new.main

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <unistd.h> // close() needed by netdog.cpp
#include "../netdog-v1.2/netdog.h"
#include "../netdog-v1.2/netdog.cpp"

void dbg(){} // for a non-moving breakpoint

int main(int argc, char** argv)
{
  dbg();
  // the usual localhost port so other netdog experiments can play too!
  printf("Listening: address '127.0.0.1', port 9999\n");
  printf("Ctrl-C to exit\n");
  
  // here's where the 'gotcha' starts.  Buffer size is 100. Not a 
  // problem... yet.  But change the 'ans' side to 200 and see 
  // what happens.
  netdog_t* pobj = netdog_new("127.0.0.1", 9999, 100);
  
  pobj->sock_flags &= ~SOCK_NONBLOCK;
  
  // The listener side will have two fd's, one for the listener 
  // and the other is created by 'accept' which is the other 
  // side of 'request'.
  
  netdog_request(pobj); // does "connect" internally
  
  for(;;)
  {
    fgets(pobj->indata, pobj->datamax, stdin);
    netdog_send(pobj, pobj->indata, pobj->datamax);
    printf("sent: %s\n", pobj->outdata);
    netdog_receive(pobj);
    printf("received: %s\n", pobj->indata);
    
    // Up in one of those lines is the listener/server side of the "gotcha".    
  }
  return 0;
}
And again, pretty simple, with 'request' on the originators side replacing 'accept' on the answer side.

Now what if...

Change the size of ans.cpp buffer to 200 instead of 100 at around line 21 of the source file and watch what happens. Run it a few times with the original size buffers in both so you get used to what it should look like and then with the double sized buffer for the ans.cpp side.

If you see the problem immediately from just the code (and there's not much of it, so this should be a breeze for a sockets wizz), good for you.

If not.. we are about to discover what's hidden in the black box that nobody talks about.

This self extractor (below) includes netdog-v1.2 and both source files... and a makefile and the mc2.def used to create it. Older netdogs won't work for this, unfortunately.

file: overload-test.sfxz
purpose: utility (executable)
Code:
#!/bin/sh
# base64 self extractor
# file: overload-test

filename=overload-test

# 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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
_BEOF

(cd $HOME/tmp/sfxz && tar -xaf overload-test.xz)
rm -f $HOME/tmp/sfxz/overload-test.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 overload-test ]; 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/overload-test .
_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
Notes:

The makefile was generated by...
Code:
mc2 -fetch cpp-32
and changed the mc2.def
OUTNAME = MULTI
Code:
make update # to write the new makefile
The self extractor was created with 'new.sfxz' available here at the blog and packs stuff up about twice as tight as tar.gz even in text mode.
http://www.linuxquestions.org/questi...archive-34465/

PS. Thanks to linux questions for their patience with the size of these sockets posts.

This is a really a big deal. There's so little simple yet useable demo code around that this stuff here is pretty important to share.

PPS. Need a hint? Couldn't figure out why the echo went missing half the time and got further and further delayed?

The orig side continues the previous read when it reads and gets a load of zeros until it has received the full amount of data from 'ans'. With a 300 byte buffer size for ans, it would take three reads to get to the second echo, and so on.

Strings like these shouldn't have been a problem because they are short, but then the amount to *send* should NEVER have been datamax. Right? (Et voila!)

Don't blame me, I downloaded the initial code from a university's 'regular' Computer Science Dept. In fact I don't even think they had a Mad Computer Science Dept. and that might have been the problem in the first place. :-)

But that still leaves us with a problem, my fellow wacked out computer freaks. Binary data. How would you solve it? How has it already been solved? And are those the best ways for your own purposes? ;-)

Find out, with netdog! Pretty easy to get working sockets, even with a gui running in the same thread. (see previous recent sockets entries and screen shots.)

- The Computer Mad Science Team

:-)
Posted in Uncategorized
Views 388 Comments 0
« Prev     Main     Next »
Total Comments 0

Comments

 

  



All times are GMT -5. The time now is 11:49 PM.

Main Menu
Advertisement

My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration