Removed old net plugin that is nolonger used. This plugin can be found in the deprecated/src/osgPlugins/net respository
This commit is contained in:
parent
7e5dd8ce17
commit
5a47744e0d
@ -1,5 +0,0 @@
|
|||||||
SET(TARGET_SRC ReaderWriterNET.cpp sockinet.cpp sockstream.cpp )
|
|
||||||
SET(TARGET_H sockinet.h sockstream.h )
|
|
||||||
SET(TARGET_EXTERNAL_LIBRARIES ${OSG_SOCKET_LIBS} )
|
|
||||||
#### end var setup ###
|
|
||||||
SETUP_PLUGIN(net)
|
|
@ -1,481 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include <osg/Notify>
|
|
||||||
|
|
||||||
#include <osgDB/Input>
|
|
||||||
#include <osgDB/Registry>
|
|
||||||
#include <osgDB/FileUtils>
|
|
||||||
#include <osgDB/FileNameUtils>
|
|
||||||
#include <osgDB/ReadFile>
|
|
||||||
#include <osgDB/WriteFile>
|
|
||||||
#include <osgDB/FileUtils>
|
|
||||||
#include <osgDB/Archive>
|
|
||||||
#include <osg/MatrixTransform>
|
|
||||||
#include <osg/Group>
|
|
||||||
#include <osg/Timer>
|
|
||||||
#include "sockinet.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Semantics:
|
|
||||||
* Two methods for using the .net loader.
|
|
||||||
* 1) Add a hostname prefix and a '.net' suffix on a model when passing
|
|
||||||
* to osgDB::readNodeFile()
|
|
||||||
* e.g: osgDB::readNodeFile( "openscenegraph.org:cow.osg.net" );
|
|
||||||
*
|
|
||||||
* 2) Explicitely load the .net plugin and pass the plugin options including
|
|
||||||
* hostname=<hostname>
|
|
||||||
*
|
|
||||||
* Method #1 takes precedence. SO, if the hostname option is passed the
|
|
||||||
* plugin, but the name also contains a hostname prefix, the hostname
|
|
||||||
* prefix on the file name will override the option
|
|
||||||
*
|
|
||||||
* Plugin options:
|
|
||||||
* hostname=<hostname> - Specify the host where the data file is to
|
|
||||||
* be fetched from.
|
|
||||||
*
|
|
||||||
* prefix=<prefix> - Specify a server directory to prefix the
|
|
||||||
* file name with.
|
|
||||||
*
|
|
||||||
* local_cache_dir=<dir> - Specify a directory in which to cache files
|
|
||||||
* on the local machine once they've been fetched.
|
|
||||||
* This directory is also searched before fetching
|
|
||||||
* the file from the server when Read mode is
|
|
||||||
* enabled on the cache.
|
|
||||||
*
|
|
||||||
* cache_mode=<mode> - Set the mode for the local cache if local_cache
|
|
||||||
* was specified. If local_cache was not specified
|
|
||||||
* this directive is ignored. <mode> may
|
|
||||||
* be specified with ReadOnly, WriteOnly, or
|
|
||||||
* ReadWrite. Behavior for the different modes is
|
|
||||||
* defined as:
|
|
||||||
*
|
|
||||||
* ReadOnly - When retrieving files, cache is
|
|
||||||
* searched first, and if the file is
|
|
||||||
* not present, it is fetched from the
|
|
||||||
* server. If it is fetched from the
|
|
||||||
* server it is not stored in local cache
|
|
||||||
*
|
|
||||||
* WriteOnly - When retrieving files, cache is not
|
|
||||||
* searched, file is always retrieved
|
|
||||||
* from the server and always written to
|
|
||||||
* cache.
|
|
||||||
*
|
|
||||||
* ReadWrite - (the default). When retrieving files
|
|
||||||
* cache is searched first, if file is
|
|
||||||
* not present in cache, it is fetched from
|
|
||||||
* the server. If fetched, it is written
|
|
||||||
* to cache.
|
|
||||||
*
|
|
||||||
* proxy_host=<hostname> - Specify the name of a Proxy host. Proxies are not
|
|
||||||
* used by default
|
|
||||||
*
|
|
||||||
* proxy_port=<portnumber> - When using a Proxy host, specify the port. The
|
|
||||||
* internal variable defaults to 8080.
|
|
||||||
*
|
|
||||||
* Environmental Variables:
|
|
||||||
*
|
|
||||||
* OSG_PROXY_HOST Specifies the name of a Proxy host. Overrides options.
|
|
||||||
*
|
|
||||||
* OSG_PROXY_PORT When using a Proxy, sets the proxy port deliberately.
|
|
||||||
* The internal variable defaults to 8080.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
class NetReader : public osgDB::ReaderWriter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NetReader()
|
|
||||||
{
|
|
||||||
supportsProtocol("http","HTTP Protocol");
|
|
||||||
supportsExtension("net","Psuedo loader extension for selecting NET plugin");
|
|
||||||
supportsExtension("*","Passes all file loading onto other plugins");
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual const char* className() const { return "HTTP Protocol Model Reader"; }
|
|
||||||
|
|
||||||
virtual bool acceptsExtension(const std::string& extension) const
|
|
||||||
{
|
|
||||||
return osgDB::equalCaseInsensitive(extension,"net");
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ObjectType
|
|
||||||
{
|
|
||||||
OBJECT,
|
|
||||||
ARCHIVE,
|
|
||||||
IMAGE,
|
|
||||||
HEIGHTFIELD,
|
|
||||||
NODE
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ReadResult openArchive(const std::string& fileName,ArchiveStatus status, unsigned int , const Options* options) const
|
|
||||||
{
|
|
||||||
if (status!=READ) return ReadResult(ReadResult::FILE_NOT_HANDLED);
|
|
||||||
else return readFile(ARCHIVE,fileName,options);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ReadResult readObject(const std::string& fileName, const Options* options) const
|
|
||||||
{
|
|
||||||
return readFile(OBJECT,fileName,options);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ReadResult readImage(const std::string& fileName, const Options *options) const
|
|
||||||
{
|
|
||||||
return readFile(IMAGE,fileName,options);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ReadResult readHeightField(const std::string& fileName, const Options *options) const
|
|
||||||
{
|
|
||||||
return readFile(HEIGHTFIELD,fileName,options);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ReadResult readNode(const std::string& fileName, const Options *options) const
|
|
||||||
{
|
|
||||||
return readFile(NODE,fileName,options);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadResult readFile(ObjectType objectType, osgDB::ReaderWriter* rw, std::istream& fin, const Options *options) const
|
|
||||||
{
|
|
||||||
switch(objectType)
|
|
||||||
{
|
|
||||||
case(OBJECT): return rw->readObject(fin,options);
|
|
||||||
case(ARCHIVE): return rw->openArchive(fin,options);
|
|
||||||
case(IMAGE): return rw->readImage(fin,options);
|
|
||||||
case(HEIGHTFIELD): return rw->readHeightField(fin,options);
|
|
||||||
case(NODE): return rw->readNode(fin,options);
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
return ReadResult::FILE_NOT_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ReadResult readFile(ObjectType objectType, const std::string& inFileName, const Options *options) const
|
|
||||||
{
|
|
||||||
osg::Timer_t start = osg::Timer::instance()->tick();
|
|
||||||
|
|
||||||
osg::notify(osg::NOTICE) << "osgPlugin .net: start load" << inFileName << std::endl;
|
|
||||||
|
|
||||||
|
|
||||||
std::string hostname;
|
|
||||||
std::string serverPrefix;
|
|
||||||
std::string localCacheDir;
|
|
||||||
int port = 80;
|
|
||||||
|
|
||||||
//CARLO: proxy modf
|
|
||||||
std::string proxyHost;
|
|
||||||
int proxyPort = 8080;
|
|
||||||
|
|
||||||
enum CacheMode {
|
|
||||||
Read = 1,
|
|
||||||
Write = 2,
|
|
||||||
ReadWrite = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string cacheFile;
|
|
||||||
CacheMode cacheMode = ReadWrite;
|
|
||||||
|
|
||||||
if (options)
|
|
||||||
{
|
|
||||||
std::istringstream iss(options->getOptionString());
|
|
||||||
std::string opt;
|
|
||||||
while (iss >> opt)
|
|
||||||
{
|
|
||||||
int index = opt.find( "=" );
|
|
||||||
if( opt.substr( 0, index ) == "hostname" ||
|
|
||||||
opt.substr( 0, index ) == "HOSTNAME" )
|
|
||||||
{
|
|
||||||
hostname = opt.substr( index+1 );
|
|
||||||
}
|
|
||||||
else if( opt.substr( 0, index ) == "port" ||
|
|
||||||
opt.substr( 0, index ) == "PORT" )
|
|
||||||
{
|
|
||||||
port = atoi( opt.substr(index+1).c_str() );
|
|
||||||
}
|
|
||||||
else if( opt.substr( 0, index ) == "proxy_hostname" ||
|
|
||||||
opt.substr( 0, index ) == "PROXY_HOSTNAME" ) //CARLO: proxy modf
|
|
||||||
{
|
|
||||||
proxyHost = opt.substr(index+1);
|
|
||||||
osg::notify(osg::WARN) << "proxy host " << proxyHost << std::endl;
|
|
||||||
}
|
|
||||||
else if( opt.substr( 0, index ) == "proxy_port" ||
|
|
||||||
opt.substr( 0, index ) == "PROXY_PORT" )
|
|
||||||
{
|
|
||||||
proxyPort = atoi( opt.substr(index+1).c_str() );
|
|
||||||
}
|
|
||||||
else if( opt.substr( 0, index ) == "server_prefix" ||
|
|
||||||
opt.substr( 0, index ) == "SERVER_PREFIX" ||
|
|
||||||
opt.substr( 0, index ) == "prefix" ||
|
|
||||||
opt.substr( 0, index ) == "PREFIX" )
|
|
||||||
{
|
|
||||||
serverPrefix = opt.substr(index+1);
|
|
||||||
}
|
|
||||||
else if( opt.substr( 0, index ) == "local_cache_dir" ||
|
|
||||||
opt.substr( 0, index ) == "LOCAL_CACHE_DIR" )
|
|
||||||
{
|
|
||||||
localCacheDir = opt.substr(index+1);
|
|
||||||
osg::notify(osg::INFO)<<"LOCAL_CACHE_DIR="<<localCacheDir<<std::endl;
|
|
||||||
}
|
|
||||||
else if( opt.substr( 0, index ) == "cache_mode" ||
|
|
||||||
opt.substr( 0, index ) == "CACHE_MODE" )
|
|
||||||
{
|
|
||||||
if( opt.substr(index+1) == "ReadOnly" )
|
|
||||||
cacheMode = Read;
|
|
||||||
else if( opt.substr(index+1) == "WriteOnly" )
|
|
||||||
cacheMode = Write;
|
|
||||||
else if( opt.substr(index+1) == "ReadWrite" )
|
|
||||||
cacheMode = ReadWrite;
|
|
||||||
else
|
|
||||||
osg::notify(osg::WARN) <<
|
|
||||||
"NET plug-in warning: cache_mode " << opt.substr(index+1) <<
|
|
||||||
" not understood. Defaulting to ReadWrite." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Env variables should override plug-in options.
|
|
||||||
{
|
|
||||||
char * env_proxyHost = getenv("OSG_PROXY_HOST"); //Checking proxy environment variables
|
|
||||||
char * env_proxyPort = getenv("OSG_PROXY_PORT");
|
|
||||||
|
|
||||||
if( env_proxyHost )
|
|
||||||
{
|
|
||||||
proxyHost = std::string(env_proxyHost);
|
|
||||||
if( env_proxyPort )
|
|
||||||
proxyPort = atoi(std::string(env_proxyPort).c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadResult readResult = ReadResult::FILE_NOT_HANDLED;
|
|
||||||
|
|
||||||
/* * we accept all extensions
|
|
||||||
std::string ext = osgDB::getFileExtension(inFileName);
|
|
||||||
if (!acceptsExtension(ext))
|
|
||||||
return ReadResult::FILE_NOT_HANDLED;
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
std::string fileName;
|
|
||||||
int index = inFileName.find_last_of(":");
|
|
||||||
// If we haven't been given a hostname as an option
|
|
||||||
// and it hasn't been prefixed to the name, we fail
|
|
||||||
if( index != -1 )
|
|
||||||
{
|
|
||||||
hostname = inFileName.substr( 0, index);
|
|
||||||
// need to strip the inFileName of the hostname prefix
|
|
||||||
fileName = inFileName.substr( index+1 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( hostname.empty() )
|
|
||||||
return ReadResult::FILE_NOT_HANDLED;
|
|
||||||
else
|
|
||||||
fileName = inFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Find the Port Number specified in URL
|
|
||||||
index = hostname.find_last_of(":");
|
|
||||||
if( index != -1 )
|
|
||||||
{
|
|
||||||
port = atoi( hostname.substr( index + 1 ).c_str() );
|
|
||||||
hostname = hostname.substr( 0, index );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let's also strip the possible .net extension
|
|
||||||
if( osgDB::getFileExtension( fileName ) == "net" )
|
|
||||||
{
|
|
||||||
int rindex = fileName.rfind( "." );
|
|
||||||
fileName = fileName.substr( 0, rindex );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !serverPrefix.empty() )
|
|
||||||
fileName = serverPrefix + '/' + fileName;
|
|
||||||
|
|
||||||
// Invoke the reader corresponding to the extension
|
|
||||||
osgDB::ReaderWriter *reader =
|
|
||||||
osgDB::Registry::instance()->getReaderWriterForExtension( osgDB::getFileExtension(fileName));
|
|
||||||
if( reader == 0L )
|
|
||||||
return ReadResult::FILE_NOT_HANDLED;
|
|
||||||
|
|
||||||
// Before we go to the network, lets see if it is in local cache, if cache
|
|
||||||
// was specified and Read bit is set
|
|
||||||
if( !localCacheDir.empty() && (cacheMode & Read) )
|
|
||||||
{
|
|
||||||
std::string cacheFile = localCacheDir + '/' + fileName;
|
|
||||||
if( osgDB::fileExists( cacheFile ))
|
|
||||||
{
|
|
||||||
std::ifstream in(cacheFile.c_str());
|
|
||||||
readResult = readFile(objectType, reader, in, options );
|
|
||||||
|
|
||||||
in.close();
|
|
||||||
osg::notify(osg::NOTICE) << "osgPlugin .net: " << fileName <<
|
|
||||||
" fetched from local cache." << std::endl;
|
|
||||||
return readResult;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
osg::notify(osg::NOTICE) << "osgPlugin .net: " << fileName <<
|
|
||||||
" could not be found in local cache." << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch from the network
|
|
||||||
osg::ref_ptr<iosockinet> sio = new iosockinet(sockbuf::sock_stream);
|
|
||||||
|
|
||||||
std::string requestAdd;
|
|
||||||
|
|
||||||
if(!proxyHost.empty())
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
sio->rdbuf()->connect( proxyHost.c_str(), proxyPort );
|
|
||||||
osg::notify(osg::DEBUG_FP) << "osgPlugin .net reader: connected to Proxy " << proxyHost << " with Port " << proxyPort << std::endl;
|
|
||||||
}
|
|
||||||
catch( sockerr e )
|
|
||||||
{
|
|
||||||
osg::notify(osg::WARN) << "osgPlugin .net reader: Unable to connect to Proxy " << proxyHost << std::endl;
|
|
||||||
return ReadResult::FILE_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(port != 80) //Default HTTP Port
|
|
||||||
{
|
|
||||||
std::ostringstream portstream;
|
|
||||||
portstream << port << std::flush;
|
|
||||||
|
|
||||||
requestAdd = std::string("http://") + hostname + std::string(":") + portstream.str() + std::string("/") + fileName;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
requestAdd = std::string("http://") + hostname + std::string("/") + fileName;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
sio->rdbuf()->connect( hostname.c_str(), port );
|
|
||||||
osg::notify(osg::DEBUG_FP) << "osgPlugin .net reader: connected to Hostname " << hostname << " with Port " << port << std::endl;
|
|
||||||
}
|
|
||||||
catch( sockerr e )
|
|
||||||
{
|
|
||||||
osg::notify(osg::WARN) << "osgPlugin .net reader: Unable to connect to host " << hostname << std::endl;
|
|
||||||
return ReadResult::FILE_NOT_FOUND;
|
|
||||||
}
|
|
||||||
requestAdd = "/" + fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sio <<
|
|
||||||
"GET " << requestAdd << " HTTP/1.1\n"
|
|
||||||
"User-Agent: OSGNetPlugin/1.0\n"
|
|
||||||
"Accept: */*\n"
|
|
||||||
"Host: " << hostname << "\n"
|
|
||||||
"Connection: close\n"
|
|
||||||
"\n";
|
|
||||||
|
|
||||||
sio->flush();
|
|
||||||
|
|
||||||
char linebuff[512];
|
|
||||||
do
|
|
||||||
{
|
|
||||||
sio->getline( linebuff, sizeof( linebuff ));
|
|
||||||
|
|
||||||
std::istringstream iss(linebuff);
|
|
||||||
std::string directive;
|
|
||||||
iss >> directive;
|
|
||||||
if( directive.substr(0,4) == "HTTP" )
|
|
||||||
{
|
|
||||||
iss >> directive;
|
|
||||||
// Code 200. We be ok.
|
|
||||||
if( directive == "200" )
|
|
||||||
;
|
|
||||||
// Code 400 Bad Request
|
|
||||||
else if( directive == "400" )
|
|
||||||
{
|
|
||||||
osg::notify(osg::WARN) <<
|
|
||||||
"osgPlugin .net: http server response 400 - Bad Request : "<<requestAdd << std::endl;
|
|
||||||
return ReadResult::FILE_NOT_FOUND;
|
|
||||||
}
|
|
||||||
// Code 401 Bad Request
|
|
||||||
else if( directive == "401" )
|
|
||||||
{
|
|
||||||
osg::notify(osg::WARN) <<
|
|
||||||
"osgPlugin .net: http server response 401 - Unauthorized Access : "<<requestAdd << std::endl;
|
|
||||||
return ReadResult::FILE_NOT_FOUND;
|
|
||||||
}
|
|
||||||
// Code 403 Bad Request
|
|
||||||
else if( directive == "403" )
|
|
||||||
{
|
|
||||||
osg::notify(osg::WARN) <<
|
|
||||||
"osgPlugin .net: http server response 403 - Access forbidden : "<<requestAdd << std::endl;
|
|
||||||
return ReadResult::FILE_NOT_FOUND;
|
|
||||||
}
|
|
||||||
// Code 404 File not found
|
|
||||||
else if( directive == "404" )
|
|
||||||
{
|
|
||||||
osg::notify(osg::WARN) <<
|
|
||||||
"osgPlugin .net: http server response 404 - File not found : "<<requestAdd<< std::endl;
|
|
||||||
return ReadResult::FILE_NOT_FOUND;
|
|
||||||
}
|
|
||||||
// Code 405 Method not allowed
|
|
||||||
else if( directive == "405" )
|
|
||||||
{
|
|
||||||
osg::notify(osg::WARN) <<
|
|
||||||
"osgPlugin .net: http server response 405 - Method Not Allowed : " <<requestAdd<< std::endl;
|
|
||||||
return ReadResult::FILE_NOT_FOUND;
|
|
||||||
}
|
|
||||||
// There's more....
|
|
||||||
}
|
|
||||||
|
|
||||||
} while( linebuff[0] != '\r' );
|
|
||||||
|
|
||||||
// code for setting up the database path so that any paged
|
|
||||||
// databases can be automatically located.
|
|
||||||
osg::ref_ptr<Options> local_opt = const_cast<Options*>(options);
|
|
||||||
if (!local_opt) local_opt = new Options;
|
|
||||||
|
|
||||||
if (local_opt.valid() && local_opt->getDatabasePathList().empty())
|
|
||||||
{
|
|
||||||
local_opt->setDatabasePath(osgDB::getFilePath(inFileName));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if( reader != 0L )
|
|
||||||
readResult = readFile(objectType, reader, *sio, local_opt.get() );
|
|
||||||
|
|
||||||
double ms = osg::Timer::instance()->delta_m(start,osg::Timer::instance()->tick());
|
|
||||||
|
|
||||||
osg::notify(osg::NOTICE) << "osgPlugin .net: " << fileName <<
|
|
||||||
" fetched from server. in " << ms <<" ms"<< std::endl;
|
|
||||||
|
|
||||||
if (objectType==ARCHIVE && readResult.validArchive())
|
|
||||||
{
|
|
||||||
// attach the socket istream to the archive to keep it alive.
|
|
||||||
osgDB::Archive* archive = readResult.getArchive();
|
|
||||||
archive->setUserData(sio.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !localCacheDir.empty() && cacheMode & Write )
|
|
||||||
{
|
|
||||||
std::string cacheFile = localCacheDir + '/' + fileName;
|
|
||||||
if( osgDB::makeDirectoryForFile( cacheFile ) )
|
|
||||||
{
|
|
||||||
|
|
||||||
switch(objectType)
|
|
||||||
{
|
|
||||||
case(OBJECT): osgDB::writeObjectFile( *(readResult.getObject()), cacheFile ); break;
|
|
||||||
case(IMAGE): osgDB::writeImageFile( *(readResult.getImage()), cacheFile ); break;
|
|
||||||
case(HEIGHTFIELD): osgDB::writeHeightFieldFile( *(readResult.getHeightField()), cacheFile ); break;
|
|
||||||
case(NODE): osgDB::writeNodeFile( *(readResult.getNode()), cacheFile ); break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
osg::notify(osg::NOTICE) << "osgPlugin .net: " << fileName <<
|
|
||||||
" stored to local cache." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return readResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
REGISTER_OSGPLUGIN(net, NetReader)
|
|
@ -1,445 +0,0 @@
|
|||||||
// sockinet.C -*- C++ -*- socket library
|
|
||||||
// Copyright (C) 2002 Herbert Straub
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
// Copyright (C) 1992-1996 Gnanasekaran Swaminathan <gs4t@virginia.edu>
|
|
||||||
//
|
|
||||||
// Permission is granted to use at your own risk and distribute this software
|
|
||||||
// in source and binary forms provided the above copyright notice and this
|
|
||||||
// paragraph are preserved on all copies. This software is provided "as is"
|
|
||||||
// with no express or implied warranty.
|
|
||||||
//
|
|
||||||
// Version: 12Jan97 1.11
|
|
||||||
// 2002-07-25 Version 1.2 (C) Herbert Straub
|
|
||||||
// Adding improved Error Handling in sockerr class
|
|
||||||
// sockinetaddr::setport if the first character of the port parameter is a
|
|
||||||
// digit, then the parameter is interpreted as a number
|
|
||||||
// 2002-07-28 Version 1.2 (C) Herbert Straub
|
|
||||||
// Eliminating sorry_about_global_temp inititialisation. This don't work
|
|
||||||
// in combination with NewsCache. My idea is: initializing the classes with (0)
|
|
||||||
// and in the second step call ios::init (sockinetbuf *) and iosockstream::init ...
|
|
||||||
// The constructors of isockinet, osockinet and iosockinet are changed.
|
|
||||||
|
|
||||||
#include "sockinet.h"
|
|
||||||
|
|
||||||
#if defined(__CYGWIN__) || !defined(WIN32)
|
|
||||||
extern "C" {
|
|
||||||
# include <netdb.h>
|
|
||||||
# include <sys/time.h>
|
|
||||||
# include <sys/socket.h>
|
|
||||||
# include <stdlib.h>
|
|
||||||
# include <unistd.h>
|
|
||||||
# include <errno.h>
|
|
||||||
# include <netinet/tcp.h>
|
|
||||||
# include <netinet/in.h>
|
|
||||||
# include <netinet/in.h>
|
|
||||||
# include <arpa/inet.h>
|
|
||||||
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
# define EADDRNOTAVAIL WSAEADDRNOTAVAIL
|
|
||||||
# define EADDRINUSE WSAEADDRINUSE
|
|
||||||
# define ENOPROTOOPT WSAENOPROTOOPT
|
|
||||||
#endif // !WIN32
|
|
||||||
|
|
||||||
#ifndef INADDR_NONE
|
|
||||||
#define INADDR_NONE ((in_addr_t) 0xffffffff)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Do not include anything below that define. That should in no case change any forward decls in
|
|
||||||
// system headers ...
|
|
||||||
#if (defined(__APPLE__)&&(__GNUC__<4)) || (defined(WIN32)&&!defined(__CYGWIN__)) || \
|
|
||||||
(!defined(__APPLE__) && !defined(WIN32) && !defined(_XOPEN_SOURCE_EXTENDED) && !defined(__FreeBSD__))
|
|
||||||
#define socklen_t int
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// need add throw() under Linux when compile with aggressive warning
|
|
||||||
// void herror(const char*) throw();
|
|
||||||
|
|
||||||
sockinetaddr::sockinetaddr ()
|
|
||||||
{
|
|
||||||
sin_family = sockinetbuf::af_inet;
|
|
||||||
sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
sin_port = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sockinetaddr::sockinetaddr(unsigned long addr, int port_no)
|
|
||||||
// addr and port_no are in host byte order
|
|
||||||
{
|
|
||||||
sin_family = sockinetbuf::af_inet;
|
|
||||||
sin_addr.s_addr = htonl(addr);
|
|
||||||
sin_port = htons(port_no);
|
|
||||||
}
|
|
||||||
|
|
||||||
sockinetaddr::sockinetaddr(unsigned long addr, const char* sn, const char* pn)
|
|
||||||
// addr is in host byte order
|
|
||||||
{
|
|
||||||
sin_family = sockinetbuf::af_inet;
|
|
||||||
sin_addr.s_addr = htonl (addr); // Added by cgay@cs.uoregon.edu May 29, 1993
|
|
||||||
setport(sn, pn);
|
|
||||||
}
|
|
||||||
|
|
||||||
sockinetaddr::sockinetaddr (const char* host_name, int port_no)
|
|
||||||
// port_no is in host byte order
|
|
||||||
{
|
|
||||||
setaddr(host_name);
|
|
||||||
sin_port = htons(port_no);
|
|
||||||
}
|
|
||||||
|
|
||||||
sockinetaddr::sockinetaddr(const char* hn, const char* sn, const char* pn)
|
|
||||||
{
|
|
||||||
setaddr(hn);
|
|
||||||
setport(sn, pn);
|
|
||||||
}
|
|
||||||
|
|
||||||
sockinetaddr::sockinetaddr (const sockinetaddr& sina): sockAddr()
|
|
||||||
{
|
|
||||||
sin_family = sockinetbuf::af_inet;
|
|
||||||
sin_addr.s_addr = sina.sin_addr.s_addr;
|
|
||||||
sin_port = sina.sin_port;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sockinetaddr::setport(const char* sn, const char* pn)
|
|
||||||
{
|
|
||||||
if (isdigit (*sn)) {
|
|
||||||
sin_port = htons(atoi(sn));
|
|
||||||
} else {
|
|
||||||
servent* sp = getservbyname(sn, pn);
|
|
||||||
if (sp == 0) throw sockerr (EADDRNOTAVAIL, "sockinetaddr::setport");
|
|
||||||
sin_port = sp->s_port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int sockinetaddr::getport () const
|
|
||||||
{
|
|
||||||
return ntohs (sin_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sockinetaddr::setaddr(const char* host_name)
|
|
||||||
{
|
|
||||||
if ( (sin_addr.s_addr = inet_addr(host_name)) == INADDR_NONE) {
|
|
||||||
hostent* hp = gethostbyname(host_name);
|
|
||||||
if (hp == 0) throw sockerr (EADDRNOTAVAIL, "sockinetaddr::setaddr");
|
|
||||||
memcpy(&sin_addr, hp->h_addr, hp->h_length);
|
|
||||||
sin_family = hp->h_addrtype;
|
|
||||||
} else
|
|
||||||
sin_family = sockinetbuf::af_inet;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* sockinetaddr::gethostname () const
|
|
||||||
{
|
|
||||||
if (sin_addr.s_addr == htonl(INADDR_ANY)) {
|
|
||||||
static char hostname[64];
|
|
||||||
if (::gethostname(hostname, 63) == -1) return "";
|
|
||||||
return hostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
hostent* hp = gethostbyaddr((const char*) &sin_addr,
|
|
||||||
sizeof(sin_addr),
|
|
||||||
family());
|
|
||||||
if (hp == 0) return "";
|
|
||||||
if (hp->h_name) return hp->h_name;
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
sockinetbuf::sockinetbuf (const sockbuf::sockdesc& sd)
|
|
||||||
: sockbuf (sd.sock)
|
|
||||||
{}
|
|
||||||
|
|
||||||
sockinetbuf::sockinetbuf(sockbuf::type ty, int proto)
|
|
||||||
: sockbuf (af_inet, ty, proto)
|
|
||||||
{}
|
|
||||||
|
|
||||||
sockinetaddr sockinetbuf::localaddr() const
|
|
||||||
{
|
|
||||||
sockinetaddr sin;
|
|
||||||
socklen_t len = sin.size();
|
|
||||||
if (::getsockname(rep->sock, sin.addr (), &len) == -1)
|
|
||||||
throw sockerr (errno, "sockinetbuf::localaddr");
|
|
||||||
return sin;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sockinetbuf::localport() const
|
|
||||||
{
|
|
||||||
sockinetaddr sin = localaddr();
|
|
||||||
if (sin.family() != af_inet) return -1;
|
|
||||||
return sin.getport();
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* sockinetbuf::localhost() const
|
|
||||||
{
|
|
||||||
sockinetaddr sin = localaddr();
|
|
||||||
if (sin.family() != af_inet) return "";
|
|
||||||
return sin.gethostname();
|
|
||||||
}
|
|
||||||
|
|
||||||
sockinetaddr sockinetbuf::peeraddr() const
|
|
||||||
{
|
|
||||||
sockinetaddr sin;
|
|
||||||
socklen_t len = sin.size();
|
|
||||||
if (::getpeername(rep->sock, sin.addr (), &len) == -1)
|
|
||||||
throw sockerr (errno, "sockinetbuf::peeraddr");
|
|
||||||
return sin;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sockinetbuf::peerport() const
|
|
||||||
{
|
|
||||||
sockinetaddr sin = peeraddr();
|
|
||||||
if (sin.family() != af_inet) return -1;
|
|
||||||
return sin.getport();
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* sockinetbuf::peerhost() const
|
|
||||||
{
|
|
||||||
sockinetaddr sin = peeraddr();
|
|
||||||
if (sin.family() != af_inet) return "";
|
|
||||||
return sin.gethostname();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sockinetbuf::bind_until_success (int portno)
|
|
||||||
// a. bind to (INADDR_ANY, portno)
|
|
||||||
// b. if success return
|
|
||||||
// c. if failure and errno is EADDRINUSE, portno++ and go to step a.
|
|
||||||
{
|
|
||||||
for (;;) {
|
|
||||||
try {
|
|
||||||
bind (portno++);
|
|
||||||
}
|
|
||||||
catch (sockerr e) {
|
|
||||||
// if (e.errno () != EADDRINUSE) throw;
|
|
||||||
if (e.serrno () != EADDRINUSE) throw; // LN
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sockinetbuf::bind (sockAddr& sa)
|
|
||||||
{
|
|
||||||
sockbuf::bind (sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sockinetbuf::bind (int port_no)
|
|
||||||
{
|
|
||||||
sockinetaddr sa ((long unsigned int) // LN
|
|
||||||
INADDR_ANY, port_no);
|
|
||||||
bind (sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sockinetbuf::bind (unsigned long addr, int port_no)
|
|
||||||
// address and portno are in host byte order
|
|
||||||
{
|
|
||||||
sockinetaddr sa (addr, port_no);
|
|
||||||
bind (sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sockinetbuf::bind (const char* host_name, int port_no)
|
|
||||||
{
|
|
||||||
sockinetaddr sa (host_name, port_no);
|
|
||||||
bind (sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sockinetbuf::bind (unsigned long addr,
|
|
||||||
const char* service_name,
|
|
||||||
const char* protocol_name)
|
|
||||||
{
|
|
||||||
sockinetaddr sa (addr, service_name, protocol_name);
|
|
||||||
bind (sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sockinetbuf::bind (const char* host_name,
|
|
||||||
const char* service_name,
|
|
||||||
const char* protocol_name)
|
|
||||||
{
|
|
||||||
sockinetaddr sa (host_name, service_name, protocol_name);
|
|
||||||
bind (sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sockinetbuf::connect (sockAddr& sa)
|
|
||||||
{
|
|
||||||
sockbuf::connect (sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sockinetbuf::connect (unsigned long addr, int port_no)
|
|
||||||
// address and portno are in host byte order
|
|
||||||
{
|
|
||||||
sockinetaddr sa (addr, port_no);
|
|
||||||
connect (sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sockinetbuf::connect (const char* host_name, int port_no)
|
|
||||||
{
|
|
||||||
sockinetaddr sa (host_name, port_no);
|
|
||||||
connect (sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sockinetbuf::connect (unsigned long addr,
|
|
||||||
const char* service_name,
|
|
||||||
const char* protocol_name)
|
|
||||||
{
|
|
||||||
sockinetaddr sa (addr, service_name, protocol_name);
|
|
||||||
connect (sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sockinetbuf::connect (const char* host_name,
|
|
||||||
const char* service_name,
|
|
||||||
const char* protocol_name)
|
|
||||||
{
|
|
||||||
sockinetaddr sa (host_name, service_name, protocol_name);
|
|
||||||
connect (sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
sockbuf::sockdesc sockinetbuf::accept ()
|
|
||||||
{
|
|
||||||
return sockbuf::accept ();
|
|
||||||
}
|
|
||||||
|
|
||||||
sockbuf::sockdesc sockinetbuf::accept (sockAddr& sa)
|
|
||||||
{
|
|
||||||
return sockbuf::accept (sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
sockbuf::sockdesc sockinetbuf::accept (unsigned long addr,
|
|
||||||
int port_no)
|
|
||||||
{
|
|
||||||
sockinetaddr sa (addr, port_no);
|
|
||||||
return accept (sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
sockbuf::sockdesc sockinetbuf::accept (const char* host_name,
|
|
||||||
int port_no)
|
|
||||||
{
|
|
||||||
sockinetaddr sa (host_name, port_no);
|
|
||||||
return accept (sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sockinetbuf::tcpnodelay () const
|
|
||||||
{
|
|
||||||
struct protoent* proto = getprotobyname ("tcp");
|
|
||||||
if (proto == 0) throw sockerr (ENOPROTOOPT, "sockinetbuf::tcpnodelay");
|
|
||||||
|
|
||||||
int old = 0;
|
|
||||||
getopt (TCP_NODELAY, &old, sizeof (old), proto->p_proto);
|
|
||||||
return old!=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sockinetbuf::tcpnodelay (bool set) const
|
|
||||||
{
|
|
||||||
struct protoent* proto = getprotobyname ("tcp");
|
|
||||||
if (proto == 0) throw sockerr (ENOPROTOOPT, "sockinetbuf::tcpnodelay");
|
|
||||||
|
|
||||||
int old = 0;
|
|
||||||
int opt = set;
|
|
||||||
getopt (TCP_NODELAY, &old, sizeof (old), proto->p_proto);
|
|
||||||
setopt (TCP_NODELAY, &opt, sizeof (opt), proto->p_proto);
|
|
||||||
return old!=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
isockinet::isockinet (const sockbuf::sockdesc& sd)
|
|
||||||
: ios(0), isockstream(0)
|
|
||||||
{
|
|
||||||
sockinetbuf *t = new sockinetbuf (sd);
|
|
||||||
|
|
||||||
ios::init (t);
|
|
||||||
isockstream::init (t);
|
|
||||||
}
|
|
||||||
|
|
||||||
isockinet::isockinet (sockbuf::type ty, int proto)
|
|
||||||
: ios (0), isockstream(0)
|
|
||||||
{
|
|
||||||
sockinetbuf *t = new sockinetbuf (ty, proto);
|
|
||||||
|
|
||||||
ios::init (t);
|
|
||||||
isockstream::init (t);
|
|
||||||
}
|
|
||||||
|
|
||||||
isockinet::isockinet (const sockinetbuf& sb)
|
|
||||||
: ios (0), isockstream(0)
|
|
||||||
{
|
|
||||||
sockinetbuf *t = new sockinetbuf (sb);
|
|
||||||
|
|
||||||
ios::init (t);
|
|
||||||
isockstream::init (t);
|
|
||||||
}
|
|
||||||
|
|
||||||
isockinet::~isockinet ()
|
|
||||||
{
|
|
||||||
delete ios::rdbuf ();
|
|
||||||
}
|
|
||||||
|
|
||||||
osockinet::osockinet (const sockbuf::sockdesc& sd)
|
|
||||||
: ios (0), osockstream(0)
|
|
||||||
{
|
|
||||||
sockinetbuf *t = new sockinetbuf (sd);
|
|
||||||
|
|
||||||
ios::init (t);
|
|
||||||
osockstream::init (t);
|
|
||||||
}
|
|
||||||
|
|
||||||
osockinet::osockinet (sockbuf::type ty, int proto)
|
|
||||||
: ios (0), osockstream(0)
|
|
||||||
{
|
|
||||||
sockinetbuf *t = new sockinetbuf (ty, proto);
|
|
||||||
|
|
||||||
ios::init (t);
|
|
||||||
osockstream::init (t);
|
|
||||||
}
|
|
||||||
|
|
||||||
osockinet::osockinet (const sockinetbuf& sb)
|
|
||||||
: ios (0), osockstream(0)
|
|
||||||
{
|
|
||||||
sockinetbuf *t = new sockinetbuf (sb);
|
|
||||||
|
|
||||||
ios::init (t);
|
|
||||||
osockstream::init (t);
|
|
||||||
}
|
|
||||||
|
|
||||||
osockinet::~osockinet ()
|
|
||||||
{
|
|
||||||
delete ios::rdbuf ();
|
|
||||||
}
|
|
||||||
|
|
||||||
iosockinet::iosockinet (const sockbuf::sockdesc& sd)
|
|
||||||
: ios (0), iosockstream(0)
|
|
||||||
{
|
|
||||||
sockinetbuf *t = new sockinetbuf(sd);
|
|
||||||
|
|
||||||
ios::init (t);
|
|
||||||
iosockstream::init (t);
|
|
||||||
}
|
|
||||||
|
|
||||||
iosockinet::iosockinet (sockbuf::type ty, int proto)
|
|
||||||
: ios (0), iosockstream (0)
|
|
||||||
{
|
|
||||||
sockinetbuf *t = new sockinetbuf (ty, proto);
|
|
||||||
|
|
||||||
ios::init (t);
|
|
||||||
iosockstream::init (t);
|
|
||||||
}
|
|
||||||
|
|
||||||
iosockinet::iosockinet (const sockinetbuf& sb)
|
|
||||||
: ios (0), iosockstream(0)
|
|
||||||
{
|
|
||||||
sockinetbuf *t = new sockinetbuf (sb);
|
|
||||||
|
|
||||||
ios::init (t);
|
|
||||||
iosockstream::init (t);
|
|
||||||
}
|
|
||||||
|
|
||||||
iosockinet::~iosockinet ()
|
|
||||||
{
|
|
||||||
delete ios::rdbuf ();
|
|
||||||
}
|
|
@ -1,139 +0,0 @@
|
|||||||
// sockinet.h -*- C++ -*- socket library
|
|
||||||
// Copyright (C) 1992-1996 Gnanasekaran Swaminathan <gs4t@virginia.edu>
|
|
||||||
//
|
|
||||||
// Permission is granted to use at your own risk and distribute this software
|
|
||||||
// in source and binary forms provided the above copyright notice and this
|
|
||||||
// paragraph are preserved on all copies. This software is provided "as is"
|
|
||||||
// with no express or implied warranty.
|
|
||||||
//
|
|
||||||
// Version: 12Jan97 1.11
|
|
||||||
|
|
||||||
#ifndef _SOCKINET_H
|
|
||||||
#define _SOCKINET_H
|
|
||||||
|
|
||||||
#include <osg/Referenced>
|
|
||||||
|
|
||||||
#include "sockstream.h"
|
|
||||||
|
|
||||||
#if defined(__CYGWIN__) || !defined(WIN32)
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif // !WIN32
|
|
||||||
|
|
||||||
class sockinetaddr: public sockAddr, public sockaddr_in
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
void setport (const char* sn, const char* pn="tcp");
|
|
||||||
void setaddr (const char* hn);
|
|
||||||
|
|
||||||
public:
|
|
||||||
~sockinetaddr () {}
|
|
||||||
sockinetaddr ();
|
|
||||||
sockinetaddr (unsigned long addr, int port_no=0);
|
|
||||||
sockinetaddr (const char* host_name, int port_no=0);
|
|
||||||
sockinetaddr (unsigned long addr,
|
|
||||||
const char* service_name,
|
|
||||||
const char* protocol_name="tcp");
|
|
||||||
sockinetaddr (const char* host_name,
|
|
||||||
const char* service_name,
|
|
||||||
const char* protocol_name="tcp");
|
|
||||||
sockinetaddr (const sockinetaddr& sina);
|
|
||||||
|
|
||||||
operator void* () const { return addr_in (); }
|
|
||||||
|
|
||||||
sockaddr_in* addr_in () const { return (sockaddr_in*) this; }
|
|
||||||
int size () const { return sizeof (sockaddr_in); }
|
|
||||||
int family() const { return sin_family; }
|
|
||||||
sockaddr* addr () const { return (sockaddr*) addr_in (); }
|
|
||||||
|
|
||||||
int getport () const;
|
|
||||||
const char* gethostname() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class sockinetbuf: public sockbuf
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum domain { af_inet = AF_INET };
|
|
||||||
|
|
||||||
sockinetbuf (const sockbuf::sockdesc& sd);
|
|
||||||
sockinetbuf (const sockinetbuf& si): sockbuf (si) {}
|
|
||||||
sockinetbuf (sockbuf::type ty, int proto=0);
|
|
||||||
sockinetbuf& operator=(const sockinetbuf& si);
|
|
||||||
~sockinetbuf () {}
|
|
||||||
|
|
||||||
sockinetaddr localaddr() const;
|
|
||||||
int localport() const;
|
|
||||||
const char* localhost() const;
|
|
||||||
|
|
||||||
sockinetaddr peeraddr() const;
|
|
||||||
int peerport() const;
|
|
||||||
const char* peerhost() const;
|
|
||||||
|
|
||||||
void bind_until_success (int portno);
|
|
||||||
|
|
||||||
virtual void bind (sockAddr& sa);
|
|
||||||
void bind (int port_no=0); // addr is assumed to be INADDR_ANY
|
|
||||||
// and thus defaults to local host
|
|
||||||
|
|
||||||
void bind (unsigned long addr, int port_no);
|
|
||||||
void bind (const char* host_name, int port_no=0);
|
|
||||||
void bind (unsigned long addr,
|
|
||||||
const char* service_name,
|
|
||||||
const char* protocol_name="tcp");
|
|
||||||
void bind (const char* host_name,
|
|
||||||
const char* service_name,
|
|
||||||
const char* protocol_name="tcp");
|
|
||||||
|
|
||||||
virtual void connect (sockAddr& sa);
|
|
||||||
void connect (unsigned long addr, int port_no);
|
|
||||||
void connect (const char* host_name, int port_no);
|
|
||||||
void connect (unsigned long addr,
|
|
||||||
const char* service_name,
|
|
||||||
const char* protocol_name="tcp");
|
|
||||||
void connect (const char* host_name,
|
|
||||||
const char* service_name,
|
|
||||||
const char* protocol_name="tcp");
|
|
||||||
|
|
||||||
virtual sockdesc accept ();
|
|
||||||
virtual sockdesc accept (sockAddr& sa);
|
|
||||||
sockdesc accept (unsigned long addr, int port_no);
|
|
||||||
sockdesc accept (const char* host_name, int port_no);
|
|
||||||
|
|
||||||
bool tcpnodelay () const;
|
|
||||||
bool tcpnodelay (bool set) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class isockinet: public isockstream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
isockinet (const sockbuf::sockdesc& sd);
|
|
||||||
isockinet (const sockinetbuf& sb);
|
|
||||||
isockinet (sockbuf::type ty=sockbuf::sock_stream, int proto=0);
|
|
||||||
~isockinet ();
|
|
||||||
|
|
||||||
sockinetbuf* rdbuf () { return (sockinetbuf*)ios::rdbuf (); }
|
|
||||||
sockinetbuf* operator -> () { return rdbuf (); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class osockinet: public osg::Referenced, public osockstream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
osockinet (const sockbuf::sockdesc& sd);
|
|
||||||
osockinet (const sockinetbuf& sb);
|
|
||||||
osockinet (sockbuf::type ty=sockbuf::sock_stream, int proto=0);
|
|
||||||
~osockinet ();
|
|
||||||
|
|
||||||
sockinetbuf* rdbuf () { return (sockinetbuf*)ios::rdbuf (); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class iosockinet: public osg::Referenced, public iosockstream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
iosockinet (const sockbuf::sockdesc& sd);
|
|
||||||
iosockinet (const sockinetbuf& sb);
|
|
||||||
iosockinet (sockbuf::type ty=sockbuf::sock_stream, int proto=0);
|
|
||||||
~iosockinet ();
|
|
||||||
|
|
||||||
sockinetbuf* rdbuf () { return (sockinetbuf*)ios::rdbuf (); }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _SOCKINET_H
|
|
File diff suppressed because it is too large
Load Diff
@ -1,383 +0,0 @@
|
|||||||
// sockstream.h -*- C++ -*- socket library
|
|
||||||
// Copyright (C) 2002 Herbert Straub
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
// Copyright (C) 1992-1996 Gnanasekaran Swaminathan <gs4t@virginia.edu>
|
|
||||||
//
|
|
||||||
// Permission is granted to use at your own risk and distribute this software
|
|
||||||
// in source and binary forms provided the above copyright notice and this
|
|
||||||
// paragraph are preserved on all copies. This software is provided "as is"
|
|
||||||
// with no express or implied warranty.
|
|
||||||
//
|
|
||||||
// Version: 12Jan97 1.11
|
|
||||||
//
|
|
||||||
// Version: 1.2 2002-07-25 Herbert Straub
|
|
||||||
// Improved Error Handling - extending the sockerr class by cOperation
|
|
||||||
// 2003-03-06 Herbert Straub
|
|
||||||
// adding sockbuf::getname und setname (sockname)
|
|
||||||
// sockbuf methods throw method name + sockname
|
|
||||||
|
|
||||||
#ifndef _SOCKSTREAM_H
|
|
||||||
#define _SOCKSTREAM_H
|
|
||||||
|
|
||||||
#include <iostream> // must be ANSI compatible
|
|
||||||
//#include <cstddef>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <string>
|
|
||||||
//#include <cstdio>
|
|
||||||
#if defined(__CYGWIN__) || !defined(WIN32)
|
|
||||||
# include <sys/types.h>
|
|
||||||
# include <sys/uio.h>
|
|
||||||
# include <sys/socket.h>
|
|
||||||
# define SOCKET int
|
|
||||||
# define SOCKET_ERROR -1
|
|
||||||
#else
|
|
||||||
# include <windows.h>
|
|
||||||
# include <wininet.h>
|
|
||||||
//# include <errno.h>
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
# pragma comment(lib, "Wininet")
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#if defined(__linux__) || defined(__CYGWIN__)
|
|
||||||
# define MSG_MAXIOVLEN 16
|
|
||||||
#endif // __linux__
|
|
||||||
|
|
||||||
// socket exception classes
|
|
||||||
class sockerr
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
string text;
|
|
||||||
public:
|
|
||||||
sockerr (int e, const char *operation = NULL): err (e)
|
|
||||||
{
|
|
||||||
if (operation != NULL)
|
|
||||||
{
|
|
||||||
text = operation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sockerr (int e, const char *operation, const char *specification) : err (e)
|
|
||||||
{
|
|
||||||
if (operation != NULL)
|
|
||||||
text = operation;
|
|
||||||
if (specification != NULL)
|
|
||||||
{
|
|
||||||
text += "(";
|
|
||||||
text += specification;
|
|
||||||
text += ")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sockerr (int e, const string &operation): err (e)
|
|
||||||
{
|
|
||||||
text = operation;
|
|
||||||
}
|
|
||||||
sockerr (const sockerr &O)
|
|
||||||
{
|
|
||||||
err = O.err;
|
|
||||||
text = O.text;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* what () const { return "sockerr"; }
|
|
||||||
const char* operation () const { return text.c_str(); }
|
|
||||||
|
|
||||||
// int errno () const { return err; }
|
|
||||||
int serrno () const { return err; } // LN
|
|
||||||
const char* errstr () const;
|
|
||||||
bool error (int eno) const { return eno == err; }
|
|
||||||
|
|
||||||
bool io () const; // non-blocking and interrupt io recoverable error.
|
|
||||||
bool arg () const; // incorrect argument supplied. recoverable error.
|
|
||||||
bool op () const; // operational error. recovery difficult.
|
|
||||||
|
|
||||||
bool conn () const; // connection error
|
|
||||||
bool addr () const; // address error
|
|
||||||
bool benign () const; // recoverable read/write error like EINTR etc.
|
|
||||||
};
|
|
||||||
|
|
||||||
class sockoob
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
const char* what () const { return "sockoob"; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// socket address classes
|
|
||||||
struct sockaddr;
|
|
||||||
|
|
||||||
class sockAddr
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~sockAddr() {}
|
|
||||||
virtual operator void* () const =0;
|
|
||||||
operator sockaddr* () const { return addr (); }
|
|
||||||
virtual int size() const =0;
|
|
||||||
virtual int family() const =0;
|
|
||||||
virtual sockaddr* addr () const =0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct msghdr;
|
|
||||||
|
|
||||||
// socket buffer class
|
|
||||||
class sockbuf: public streambuf
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum type {
|
|
||||||
sock_stream = SOCK_STREAM,
|
|
||||||
sock_dgram = SOCK_DGRAM,
|
|
||||||
sock_raw = SOCK_RAW,
|
|
||||||
sock_rdm = SOCK_RDM,
|
|
||||||
sock_seqpacket = SOCK_SEQPACKET
|
|
||||||
};
|
|
||||||
enum option {
|
|
||||||
so_debug = SO_DEBUG,
|
|
||||||
so_reuseaddr = SO_REUSEADDR,
|
|
||||||
so_keepalive = SO_KEEPALIVE,
|
|
||||||
so_dontroute = SO_DONTROUTE,
|
|
||||||
so_broadcast = SO_BROADCAST,
|
|
||||||
so_linger = SO_LINGER,
|
|
||||||
so_oobinline = SO_OOBINLINE,
|
|
||||||
so_sndbuf = SO_SNDBUF,
|
|
||||||
so_rcvbuf = SO_RCVBUF,
|
|
||||||
so_error = SO_ERROR,
|
|
||||||
so_type = SO_TYPE
|
|
||||||
};
|
|
||||||
enum level {
|
|
||||||
sol_socket = SOL_SOCKET
|
|
||||||
};
|
|
||||||
enum msgflag {
|
|
||||||
msg_oob = MSG_OOB,
|
|
||||||
msg_peek = MSG_PEEK,
|
|
||||||
msg_dontroute = MSG_DONTROUTE
|
|
||||||
|
|
||||||
#if !(defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__))
|
|
||||||
,msg_maxiovlen = MSG_MAXIOVLEN
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
enum shuthow {
|
|
||||||
shut_read,
|
|
||||||
shut_write,
|
|
||||||
shut_readwrite
|
|
||||||
};
|
|
||||||
enum { somaxconn = SOMAXCONN };
|
|
||||||
struct socklinger {
|
|
||||||
int l_onoff; // option on/off
|
|
||||||
int l_linger; // linger time
|
|
||||||
|
|
||||||
socklinger (int a, int b): l_onoff (a), l_linger (b) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef char char_type;
|
|
||||||
typedef streampos pos_type;
|
|
||||||
typedef streamoff off_type;
|
|
||||||
typedef int int_type;
|
|
||||||
typedef int seekdir;
|
|
||||||
// const int_type eof = EOF;
|
|
||||||
enum { eof = EOF }; // LN
|
|
||||||
|
|
||||||
struct sockdesc {
|
|
||||||
int sock;
|
|
||||||
sockdesc (int d): sock (d) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
struct sockcnt {
|
|
||||||
SOCKET sock;
|
|
||||||
int cnt;
|
|
||||||
int stmo; // -1==block, 0==poll, >0 == waiting time in secs
|
|
||||||
int rtmo; // -1==block, 0==poll, >0 == waiting time in secs
|
|
||||||
bool oob; // check for out-of-band byte while reading
|
|
||||||
void* gend; // end of input buffer
|
|
||||||
void* pend; // end of output buffer
|
|
||||||
|
|
||||||
sockcnt(SOCKET s):
|
|
||||||
sock(s), cnt(1), stmo (-1), rtmo (-1), oob (false),
|
|
||||||
gend (0), pend (0) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
sockcnt* rep; // counts the # refs to sock
|
|
||||||
string sockname; // name of sockbuf - Herbert Straub
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
virtual sockbuf* setbuf (char_type* s, int_type* n);
|
|
||||||
virtual pos_type seekoff (off_type off,
|
|
||||||
seekdir way,
|
|
||||||
ios::openmode which = ios::in|ios::out);
|
|
||||||
virtual pos_type seekpos (pos_type sp,
|
|
||||||
ios::openmode which = ios::in|ios::out);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
virtual int sync ();
|
|
||||||
|
|
||||||
virtual int showmanyc () const;
|
|
||||||
virtual streamsize xsgetn (char_type* s, streamsize n);
|
|
||||||
virtual int_type underflow ();
|
|
||||||
virtual int_type uflow ();
|
|
||||||
|
|
||||||
virtual int_type pbackfail (int_type c = eof);
|
|
||||||
|
|
||||||
virtual streamsize xsputn (const char_type* s, streamsize n);
|
|
||||||
virtual int_type overflow (int_type c = eof);
|
|
||||||
|
|
||||||
public:
|
|
||||||
sockbuf (const sockdesc& sd);
|
|
||||||
sockbuf (int domain, type, int proto);
|
|
||||||
sockbuf (const sockbuf&);
|
|
||||||
// sockbuf& operator = (const sockbuf&);
|
|
||||||
virtual ~sockbuf ();
|
|
||||||
|
|
||||||
int sd () const { return rep->sock; }
|
|
||||||
int pubsync () { return sync (); }
|
|
||||||
virtual bool is_open () const;
|
|
||||||
|
|
||||||
virtual void bind (sockAddr&);
|
|
||||||
virtual void connect (sockAddr&);
|
|
||||||
|
|
||||||
void listen (int num=somaxconn);
|
|
||||||
virtual sockdesc accept();
|
|
||||||
virtual sockdesc accept(sockAddr& sa);
|
|
||||||
|
|
||||||
int read(void* buf, int len);
|
|
||||||
int recv (void* buf, int len, int msgf=0);
|
|
||||||
int recvfrom(sockAddr& sa, void* buf, int len, int msgf=0);
|
|
||||||
|
|
||||||
#if !defined(__linux__) && !defined(WIN32)
|
|
||||||
int recvmsg(msghdr* msg, int msgf=0);
|
|
||||||
int sendmsg(msghdr* msg, int msgf=0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int write(const void* buf, int len);
|
|
||||||
int send(const void* buf, int len, int msgf=0);
|
|
||||||
int sendto (sockAddr& sa, const void* buf, int len, int msgf=0);
|
|
||||||
|
|
||||||
int sendtimeout (int wp=-1);
|
|
||||||
int recvtimeout (int wp=-1);
|
|
||||||
int is_readready (int wp_sec, int wp_usec=0) const;
|
|
||||||
int is_writeready (int wp_sec, int wp_usec=0) const;
|
|
||||||
int is_exceptionpending (int wp_sec, int wp_usec=0) const;
|
|
||||||
|
|
||||||
void shutdown (shuthow sh);
|
|
||||||
|
|
||||||
int getopt(int op, void* buf, int len,
|
|
||||||
int level=sol_socket) const;
|
|
||||||
void setopt(int op, void* buf, int len,
|
|
||||||
int level=sol_socket) const;
|
|
||||||
|
|
||||||
type gettype () const;
|
|
||||||
int clearerror () const;
|
|
||||||
bool debug () const;
|
|
||||||
bool debug (bool set) const;
|
|
||||||
bool reuseaddr () const;
|
|
||||||
bool reuseaddr (bool set) const;
|
|
||||||
bool keepalive () const;
|
|
||||||
bool keepalive (bool set) const;
|
|
||||||
bool dontroute () const;
|
|
||||||
bool dontroute (bool set) const;
|
|
||||||
bool broadcast () const;
|
|
||||||
bool broadcast (bool set) const;
|
|
||||||
bool oobinline () const;
|
|
||||||
bool oobinline (bool set) const;
|
|
||||||
bool oob () const { return rep->oob; }
|
|
||||||
bool oob (bool b);
|
|
||||||
int sendbufsz () const;
|
|
||||||
int sendbufsz (int sz) const;
|
|
||||||
int recvbufsz () const;
|
|
||||||
int recvbufsz (int sz) const;
|
|
||||||
socklinger linger() const;
|
|
||||||
socklinger linger(socklinger opt) const;
|
|
||||||
socklinger linger(int onoff, int tm) const
|
|
||||||
{ return linger (socklinger (onoff, tm)); }
|
|
||||||
|
|
||||||
bool atmark() const;
|
|
||||||
long nread() const;
|
|
||||||
long howmanyc() const;
|
|
||||||
void nbio(bool set=true) const;
|
|
||||||
inline void setname(const char *name);
|
|
||||||
inline void setname(const string &name);
|
|
||||||
inline const string& getname();
|
|
||||||
|
|
||||||
#if defined(__CYGWIN__) || !defined(WIN32)
|
|
||||||
void async(bool set=true) const;
|
|
||||||
#endif
|
|
||||||
#if !defined(WIN32)
|
|
||||||
int pgrp() const;
|
|
||||||
int pgrp(int new_pgrp) const;
|
|
||||||
void closeonexec(bool set=true) const;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class isockstream: public istream
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
//isockstream (): istream(rdbuf()), ios (0) {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
isockstream(sockbuf* sb): ios (sb) , istream(sb) {}
|
|
||||||
virtual ~isockstream () {}
|
|
||||||
|
|
||||||
sockbuf* rdbuf () { return (sockbuf*)ios::rdbuf(); }
|
|
||||||
sockbuf* operator -> () { return rdbuf(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class osockstream: public ostream
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
//osockstream (): ostream(static_cast<>rdbuf()), ios (0) {}
|
|
||||||
public:
|
|
||||||
osockstream(sockbuf* sb): ios (sb) , ostream(sb) {}
|
|
||||||
virtual ~osockstream () {}
|
|
||||||
sockbuf* rdbuf () { return (sockbuf*)ios::rdbuf(); }
|
|
||||||
sockbuf* operator -> () { return rdbuf(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class iosockstream: public iostream
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
iosockstream ();
|
|
||||||
public:
|
|
||||||
iosockstream(sockbuf* sb): ios(sb), iostream(sb) {}
|
|
||||||
virtual ~iosockstream () {}
|
|
||||||
|
|
||||||
sockbuf* rdbuf () { return (sockbuf*)ios::rdbuf(); }
|
|
||||||
sockbuf* operator -> () { return rdbuf(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// manipulators
|
|
||||||
extern osockstream& crlf (osockstream&);
|
|
||||||
extern osockstream& lfcr (osockstream&);
|
|
||||||
|
|
||||||
// inline
|
|
||||||
|
|
||||||
void sockbuf::setname (const char *name)
|
|
||||||
{
|
|
||||||
sockname = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sockbuf::setname (const string &name)
|
|
||||||
{
|
|
||||||
sockname = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const string& sockbuf::getname ()
|
|
||||||
{
|
|
||||||
return sockname;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _SOCKSTREAM_H
|
|
Loading…
Reference in New Issue
Block a user