So this is just a very simple example of where to start released into the public domain. Do as you please with it. It still needs some work, so if you make improvements, it would be nice to reply here or publish as public domain aswell.
Oobles.
Code: Select all
// Created by David Ryan.
// Released into public domain Feb 2004.
// Please improve and set free again.
using namespace std;
#include <streambuf>
#include <iostream>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#ifndef TIOCINQ
#define TIOCINQ FIONREAD
#endif
class socket_buf : public streambuf
{
private:
int _socket;
char _inBuffer[1024];
char _outBuffer[1024];
public:
socket_buf( int socket )
{
_socket = socket;
setg( _inBuffer, _inBuffer, _inBuffer );
setp( _outBuffer, _outBuffer+1024 );
}
protected:
int overflow(int x)
{
cout << "socket_buf::overflow()" << x << endl;
return x;
}
int sync()
{
cout << "socket_buf::sync()" << endl;
// if no data availalbe just return.
if ( pbase() == pptr() )
return 0;
// try and send the data.
int len = pptr() - pbase();
int rc = send( _socket, pbase(), len, 0 );
if ( rc < 0 )
return rc;
setp( _outBuffer, _outBuffer+1024 );
return 0;
}
int underflow()
{
cout << "socket_buf::underflow() " << endl;
if (gptr () < egptr ()) return *(unsigned char*)gptr ();
int len;
// find out how much data is available.
if( ioctl( _socket, TIOCINQ, &len) < 0 )
{
// error
cout << "socket_buf error" << endl;
len = 1;
}
// make sure length is atleast 1. We will block.
if ( len == 0 )
len = 1;
// try and read in some data.
int read = recv( _socket, &_inBuffer, len, 0 );
if ( read > 0 )
{
setg( _inBuffer, _inBuffer, _inBuffer+read );
}
else
{
return EOF;
}
return *(unsigned char*)gptr ();
}
};
class siostream: public iostream
{
private:
socket_buf _buf;
public:
siostream( int socket )
:_buf( socket ), iostream( &_buf )
{
}
};
int main( int argc, char *argv[] )
{
int port = 95;
cout << "test socket" << endl;
struct hostent *he=gethostbyname(argv[1]);
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = PF_INET;
sa.sin_addr = *((struct in_addr *)he->h_addr);
sa.sin_port = htons(port);
int s = socket(AF_INET, SOCK_STREAM, 0);
int rv = connect( s, (struct sockaddr*) &sa, sizeof(sa) );
cout << "connect = " << rv << endl;
siostream sock( s );
sock << "23" << endl;
sock.flush();
cout << "got =" << sock.get() << endl;
cout << "finished" << endl;
}