First implementation of socket stream classes derived
authorArjen Baart <arjen@andromeda.nl>
Wed, 31 Oct 2012 14:32:46 +0000 (15:32 +0100)
committerArjen Baart <arjen@andromeda.nl>
Wed, 31 Oct 2012 14:32:46 +0000 (15:32 +0100)
from iostream classes.

include/sockstream.h [new file with mode: 0644]
test/Makefile.am
test/intest.cpp [new file with mode: 0644]
test/iptest.cpp
test/outtest.cpp [new file with mode: 0644]
test/stream [new file with mode: 0755]

diff --git a/include/sockstream.h b/include/sockstream.h
new file mode 100644 (file)
index 0000000..d6352af
--- /dev/null
@@ -0,0 +1,217 @@
+/**************************************************************************
+**  (c) Copyright 2012, Andromeda Technology & Automation
+***************************************************************************
+** MODULE INFORMATION *
+***********************
+**      FILE NAME      : sockstream.h
+**      SYSTEM NAME    : Socket stream classes
+**      VERSION NUMBER : 0.1
+**
+**  DESCRIPTION      :  sockbuf and sockstream classes.
+**
+**  EXPORTED OBJECTS : class sockbuf, class isockstream,
+**                     class osockstream, class sockstream
+**  LOCAL    OBJECTS : 
+**  MODULES  USED    :
+***************************************************************************
+**  ADMINISTRATIVE INFORMATION *
+********************************
+**      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
+**      CREATION DATE   : Aug 16, 2012
+**      LAST UPDATE     : Oct 19, 2012
+**      MODIFICATIONS   : 
+**************************************************************************/
+
+#include <ios>
+#include "socket.h"
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+**  NAME           : basic_sockbuf - Template class that applies basic_streambuf to sockets.
+**  MEMBERS        : sock       : Socket object that holds the network socket.
+**  OPERATORS      : None
+**  METHODS        : connect()        : Connect the sockbuf to a Socket object.
+**                   close()          : Close the UNIX file descriptor in the Socket.
+**                   overflow()       : Override the base class function overflow.
+**                   underflow()      : Override the base class function underflow.
+**
+**  DESCRIPTION    : 
+**
+**
+**  RELATIONS      : std::basic_streambuf, Socket
+**  SEE ALSO       : 
+**  LAST MODIFIED  : Oct 19, 2012
+**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+*/
+
+#define SOCKBUFSIZE  1500
+
+template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
+   class basic_sockbuf : public std::basic_streambuf<_CharT, _Traits>
+{
+private:
+   StreamSocket sock;
+
+   _CharT gbuf[SOCKBUFSIZE];
+   _CharT pbuf[SOCKBUFSIZE];
+
+public:
+
+   basic_sockbuf()
+   {
+      setg(gbuf,gbuf+SOCKBUFSIZE,gbuf+SOCKBUFSIZE);  // set get area
+      setp(pbuf,pbuf+SOCKBUFSIZE);                   // set put area
+   }
+
+   virtual ~basic_sockbuf()
+   {
+      sync();
+   }
+
+   void connect(StreamSocket s)
+   {
+      sock = s;
+   }
+
+   void close()
+   {
+      sock.Close();
+   }
+
+   virtual int underflow()
+   {
+      int bytes_read = sock.Read(gbuf, SOCKBUFSIZE);
+      if (bytes_read > 0)
+      {
+         setg(gbuf, gbuf, gbuf + bytes_read);
+         return 0;
+      }
+      else
+      {
+         return -1;
+      }
+   }
+
+   virtual int overflow(int c)
+   {
+      sync();
+      if (c != _Traits::eof() )
+      {
+         *this->pptr() = c;
+         this->pbump(1);
+      }
+      return c;
+   }
+
+   virtual int sync()
+   {
+      // check if there's data to flush
+      if (this->pptr() > this->pbase())
+      {
+         sock.Write(pbuf, this->pptr() - pbuf);
+         setp(pbuf, pbuf + SOCKBUFSIZE);       // reset put area
+      }
+      return 0;
+   }
+};
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+**  NAME           : basic_isockstream
+**  MEMBERS        : 
+**  OPERATORS      : None
+**  METHODS        : 
+**
+**  DESCRIPTION    : 
+**
+**
+**  RELATIONS      : 
+**  SEE ALSO       : 
+**  LAST MODIFIED  : Oct 19, 2012
+**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+*/
+
+template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
+    class basic_isockstream : public std::basic_istream<_CharT, _Traits>
+{
+private:
+   basic_sockbuf<_CharT, _Traits>   _M_sockbuf;
+
+public:
+   basic_isockstream(StreamSocket _s)
+   {
+      this->init(&_M_sockbuf);
+      _M_sockbuf.connect(_s);
+   }
+};
+
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+**  NAME           : basic_osockstream
+**  MEMBERS        : 
+**  OPERATORS      : None
+**  METHODS        : 
+**
+**  DESCRIPTION    : 
+**
+**
+**  RELATIONS      : 
+**  SEE ALSO       : 
+**  LAST MODIFIED  : Oct 19, 2012
+**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+*/
+
+template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
+    class basic_osockstream : public std::basic_ostream<_CharT,_Traits>
+{
+private:
+   basic_sockbuf<_CharT, _Traits>   _M_sockbuf;
+
+public:
+   basic_osockstream(StreamSocket _s)
+   {
+      this->init(&_M_sockbuf);
+      _M_sockbuf.connect(_s);
+   }
+};
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+**  NAME           : basic_sockstream
+**  MEMBERS        : 
+**  OPERATORS      : None
+**  METHODS        : 
+**
+**  DESCRIPTION    : 
+**
+**
+**  RELATIONS      : 
+**  SEE ALSO       : 
+**  LAST MODIFIED  : Oct 19, 2012
+**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+*/
+
+template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
+    class basic_sockstream : public std::basic_iostream<_CharT, _Traits>
+{
+private:
+   basic_sockbuf<_CharT, _Traits>   _M_sockbuf;
+
+public:
+   basic_sockstream(StreamSocket _s)
+   {
+      this->init(&_M_sockbuf);
+      _M_sockbuf.connect(_s);
+   }
+};
+
+
+//  Predefined buffer and stream types
+
+typedef basic_sockbuf<char>          sockbuf;
+typedef basic_isockstream<char>      isockstream;
+typedef basic_osockstream<char>      osockstream;
+typedef basic_sockstream<char>       sockstream;
+
+typedef basic_sockbuf<wchar_t>       wsockbuf;
+typedef basic_isockstream<wchar_t>   wisockstream;
+typedef basic_osockstream<wchar_t>   wosockstream;
+typedef basic_sockstream<wchar_t>    wsockstream;
+
index 6396368..24b5c6c 100644 (file)
@@ -1,11 +1,23 @@
-check_PROGRAMS = iptest revd
+check_PROGRAMS = iptest revd intest outtest http_get
 
 iptest_SOURCES = iptest.cpp
 iptest_CPPFLAGS = -I$(top_srcdir)/include
 iptest_LDADD = $(top_builddir)/src/libsockstream.la
 
+http_get_SOURCES = iptest.cpp
+http_get_CPPFLAGS = -I$(top_srcdir)/include
+http_get_LDADD = $(top_builddir)/src/libsockstream.la
+
 revd_SOURCES = revd.cpp
 revd_CPPFLAGS = -I$(top_srcdir)/include
 revd_LDADD = $(top_builddir)/src/libsockstream.la
 
-TESTS = iptest revd
+intest_SOURCES = intest.cpp
+intest_CPPFLAGS = -I$(top_srcdir)/include
+intest_LDADD = $(top_builddir)/src/libsockstream.la
+
+outtest_SOURCES = outtest.cpp
+outtest_CPPFLAGS = -I$(top_srcdir)/include
+outtest_LDADD = $(top_builddir)/src/libsockstream.la
+
+TESTS = iptest stream
diff --git a/test/intest.cpp b/test/intest.cpp
new file mode 100644 (file)
index 0000000..015d3b5
--- /dev/null
@@ -0,0 +1,61 @@
+/**************************************************************************
+**  (c) Copyright 2012, Andromeda Technology & Automation
+***************************************************************************
+** MODULE INFORMATION *
+***********************
+**      FILE NAME      : intest.cpp
+**      SYSTEM NAME    : Network and socket classes - test routine
+**      VERSION NUMBER : 0.1
+**
+**  DESCRIPTION      :  Input stream test.
+**                      Connects to TCP port 1234 and reads a line.
+**                      Test with: echo "this is a test"|nc -l 1234
+**
+**  EXPORTED OBJECTS : 
+**  LOCAL    OBJECTS : 
+**  MODULES  USED    :
+***************************************************************************
+**  ADMINISTRATIVE INFORMATION *
+********************************
+**      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
+**      CREATION DATE   : Oct 19, 2012
+**      LAST UPDATE     : Oct 29, 2012
+**      MODIFICATIONS   : 
+**************************************************************************/
+
+#include "sockstream.h"
+
+
+/*=========================================================================
+**  NAME           : main
+**  SYNOPSIS       :
+**  PARAMETERS     :
+**  RETURN VALUE   : None
+**
+**  DESCRIPTION    : Read lines of text from port 1234 and echo these lines
+**                   to cout.
+**
+**  VARS USED      :
+**  VARS CHANGED   :
+**  FUNCTIONS USED :
+**  SEE ALSO       :
+**  LAST MODIFIED  : Oct 29, 2012
+**=========================================================================
+*/
+
+int main()
+{
+   IPSocketAddress serveraddress(InternetAddress("127.0.0.1"), Port(1234));
+
+   StreamSocket s;
+
+   s.Connect(serveraddress);
+   isockstream reader(s);
+
+   String buf;
+   while (reader >> buf)
+   {
+      std::cout << buf << "\n";
+   }
+}
+
index 221b0fe..48dd6d9 100644 (file)
@@ -51,39 +51,6 @@ int main()
 
    std::cout << String(ip) << "\n";
 
-   std::cout << "Finding www.noortict.nl\n";
-   Host server(String("www.noortict.nl"));
-   std::list<InternetAddress> iplist = server.FindAddress();
-   std::list<InternetAddress>::iterator ipaddress;
-   for (ipaddress = iplist.begin(); ipaddress != iplist.end(); ipaddress++)
-   {
-      std::cout << "  IP address " << String(*ipaddress) << "\n";
-   }
-
-   Service srv("http");
-   std::list<Port> portlist = srv.FindAddress();
-   std::list<Port>::iterator port;
-   for (port = portlist.begin(); port != portlist.end(); port++)
-   {
-      std::cout << "  Port " << port->get_port() << ", socket type " << port->get_sockettype() << "\n";
-   }
-
-   IPSocketAddress serveraddress(iplist.front(), portlist.front());
-   StreamSocket s;
-
-   std::cout << "Connection result = " << s.Connect(serveraddress) << "\n";
-   s.Write("GET / HTTP/1.1\n", 15);
-   s.Write("Host: www.noortict.nl\n\n", 23);
-
-   char buf[1000];
-   int  len;
-   do
-   {
-      len = s.Read(buf, 1000);
-      buf[len] = '\0';
-      std::cout << "LEN = " << len << "\n" << buf << "\n";
-   }
-   while (len > 0);
 
 }
 
diff --git a/test/outtest.cpp b/test/outtest.cpp
new file mode 100644 (file)
index 0000000..114c3e3
--- /dev/null
@@ -0,0 +1,61 @@
+/**************************************************************************
+**  (c) Copyright 2012, Andromeda Technology & Automation
+***************************************************************************
+** MODULE INFORMATION *
+***********************
+**      FILE NAME      : outtest.cpp
+**      SYSTEM NAME    : Network and socket classes - test routine
+**      VERSION NUMBER : 0.1
+**
+**  DESCRIPTION      :  Output stream test.
+**                      Connects to TCP port 1234 and writes a line.
+**                      Test with: nc -l 1234
+**
+**  EXPORTED OBJECTS : 
+**  LOCAL    OBJECTS : 
+**  MODULES  USED    :
+***************************************************************************
+**  ADMINISTRATIVE INFORMATION *
+********************************
+**      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
+**      CREATION DATE   : Oct 19, 2012
+**      LAST UPDATE     : Oct 30, 2012
+**      MODIFICATIONS   : 
+**************************************************************************/
+
+#include "sockstream.h"
+
+
+/*=========================================================================
+**  NAME           : main
+**  SYNOPSIS       :
+**  PARAMETERS     :
+**  RETURN VALUE   : None
+**
+**  DESCRIPTION    : Read lines of text from port 1234 and echo these lines
+**                   to cout.
+**
+**  VARS USED      :
+**  VARS CHANGED   :
+**  FUNCTIONS USED :
+**  SEE ALSO       :
+**  LAST MODIFIED  : Oct 29, 2012
+**=========================================================================
+*/
+
+int main()
+{
+   IPSocketAddress serveraddress(InternetAddress("127.0.0.1"), Port(1234));
+
+   StreamSocket s;
+
+   s.Connect(serveraddress);
+   osockstream writer(s);
+
+   String buf;
+   while (std::cin >> buf)
+   {
+      writer << buf << std::endl;
+   }
+}
+
diff --git a/test/stream b/test/stream
new file mode 100755 (executable)
index 0000000..261d184
--- /dev/null
@@ -0,0 +1,36 @@
+#!/bin/bash
+#
+#   Test script for socket stream classes.
+#   Use a few test programs to test stream communication
+#   through sockets.
+#
+
+TESTSTRING="this is a test"
+
+#
+# Test the iscokstream class
+#
+
+echo $TESTSTRING|nc -l 1234 &
+OUT=$(./intest)
+if [ "$OUT" = "$TESTSTRING" ]
+then
+   echo "  isockstream OK."
+else
+   echo "  isockstream Fail."
+fi
+
+#
+# Test the oscokstream class
+#
+
+nc -l 1234 >stream.out&
+echo $TESTSTRING |./outtest
+read OUT <stream.out
+rm stream.out
+if [ "$OUT" = "$TESTSTRING" ]
+then
+   echo "  osockstream OK."
+else
+   echo "  osockstream Fail."
+fi