00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef INDRI_NETWORKSTREAM_HPP
00020 #define INDRI_NETWORKSTREAM_HPP
00021
00022 #include "lemur-platform.h"
00023 #include "lemur-compat.hpp"
00024 #include <string>
00025
00026 class NetworkStream {
00027 private:
00028 socket_t _socket;
00029
00030 struct sockaddr_in _getSockaddr( const char* name, unsigned int port ) {
00031 long address;
00032
00033 if( name && isdigit(name[0]) ) {
00034 address = inet_addr(name);
00035 } else {
00036 hostent* host = gethostbyname(name);
00037
00038 if( host && host->h_length ) {
00039 address = *( (long*) host->h_addr );
00040 }
00041 }
00042
00043 struct sockaddr_in sa;
00044
00045 sa.sin_addr.s_addr = address;
00046 sa.sin_port = htons(port);
00047 sa.sin_family = AF_INET;
00048 memset(&sa.sin_zero, 0, sizeof sa.sin_zero );
00049
00050 return sa;
00051 }
00052
00053 public:
00054 NetworkStream() : _socket(-1) {}
00055 NetworkStream( socket_t s ) : _socket(s) {}
00056 ~NetworkStream() {
00057 close();
00058 }
00059
00060 bool connect( const std::string& name, unsigned int port ) {
00061 return connect(name.c_str(), port);
00062 }
00063
00064 bool connect( const char* name, unsigned int port ) {
00065 lemur_compat::initializeNetwork();
00066
00067 _socket = ::socket( AF_INET, SOCK_STREAM, 0 );
00068 struct sockaddr_in sa = _getSockaddr( name, port );
00069 int result = ::connect( _socket, (const sockaddr*) &sa, sizeof sa );
00070
00071 if( result ) {
00072 close();
00073 }
00074
00075 return !result;
00076 }
00077
00078 void close() {
00079 lemur_compat::closesocket( _socket );
00080 _socket = -1;
00081 }
00082
00083 int write( const void* buffer, size_t length ) {
00084 return ::send( _socket, (const char*) buffer, int(length), 0 );
00085 }
00086
00087 int read( void* buffer, size_t length ) {
00088 return ::recv( _socket, (char*) buffer, int(length), 0 );
00089 }
00090
00091 int blockingRead( void* buffer, size_t length ) {
00092 size_t bytesRead = 0;
00093 size_t chunkRead = 0;
00094 int result;
00095
00096 while( bytesRead < (int) length ) {
00097 chunkRead = length - bytesRead;
00098 result = read( (char*)buffer + bytesRead, chunkRead );
00099
00100 if( result <= 0 ) {
00101 close();
00102 return int(bytesRead);
00103 }
00104
00105 bytesRead += result;
00106 }
00107
00108 return int(bytesRead);
00109 }
00110
00111 int blockingWrite( const void* buffer, unsigned int length ) {
00112 size_t bytesWritten = 0;
00113
00114 while( bytesWritten < (int) length ) {
00115 size_t chunkWrite = length - bytesWritten;
00116 int result = write( (const char*)buffer + bytesWritten, chunkWrite );
00117
00118 if( result <= 0 ) {
00119 close();
00120 return int(bytesWritten);
00121 }
00122
00123 bytesWritten += result;
00124 }
00125
00126 return int(bytesWritten);
00127 }
00128
00129 bool alive() {
00130 return _socket != -1;
00131 }
00132 };
00133
00134 #endif // INDRI_NETWORKSTREAM_HPP