00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef __SOCKET_H__
00027 #define __SOCKET_H__
00028
00041
00042 #include <string>
00043 #include <sstream>
00044 #include <iostream>
00045 #include <iomanip>
00046
00047
00048 #include <string.h>
00049 #include <stdio.h>
00050 #include <errno.h>
00051
00052
00053 #include <cbits/SocketException.h>
00054 #include <cbits/Timing.h>
00055 #include <cbits/CriticalSection.h>
00056 #include <cbits/sockstreambuf.h>
00057 #include <cbits/CriticalSection.h>
00058 #include <cbits/ServerSocket.h>
00059
00060
00061 #ifdef WIN32
00062
00063
00064
00065
00066
00067 #include <winsock>
00068 #include <cbits/wsa_strerror.h>
00069
00070
00071
00072
00073 #ifdef BUILD_DLL
00074 #define EXPORT __declspec(dllexport)
00075 #else
00076 #define EXPORT
00077 #endif
00078
00079
00080 #else
00081
00082
00083 #define EXPORT
00084
00085
00086
00087
00088 #include <sys/types.h>
00089 #include <sys/time.h>
00090 #include <sys/socket.h>
00091 #include <sys/select.h>
00092 #include <netdb.h>
00093 #include <netinet/in.h>
00094 #include <arpa/inet.h>
00095 #include <unistd.h>
00096 #include <fcntl.h>
00097
00098 #endif
00099
00100
00101 namespace cbits {
00102
00103
00104 class SocketExcetion;
00105
00106
00107 #ifdef WIN32
00108
00109
00110
00111
00112
00113 #define ERRNO h_errno
00114
00115
00116
00117
00118 typedef SOCKET socket_t;
00119 #define CLOSE_SOCKET(s) closesocket((s))
00120 #define GET_SOCKET_ERROR() WSAGetLastError()
00121 #define STRERROR(a) wsa_strerror(a)
00122 #define SOCKET_IS_VALID(a) ((a)==INVALID_SOCKET?false:true)
00123 #define SOCKET_EINTR WSAEINTR
00124 #define SOCKET_EAGAIN WSAEWOULDBLOCK
00125 #define SOCKET_ECONNRESET WSAECONNRESET
00126
00127 typedef long int ssize_t;
00128
00129 #else
00130
00131
00132
00133
00134
00135 #define ERRNO errno
00136
00137
00138
00139
00140 typedef int socket_t;
00141 #define CLOSE_SOCKET(s) ::close((s))
00142 #define GET_SOCKET_ERROR() errno
00143 #define STRERROR(a) strerror(a)
00144 #define SOCKET_IS_VALID(a) (0<(a)?true:false)
00145 #define SOCKET_EINTR EINTR
00146 #define SOCKET_EAGAIN EAGAIN
00147 #define SOCKET_ECONNRESET ECONNRESET
00148
00149
00150 #endif
00151
00152 #include <cbits/portable_mutex.h>
00153
00154
00155
00190 class EXPORT Socket
00191 {
00192
00193 public:
00194
00205 Socket
00206 (
00207 const std::string& host,
00209 const int port,
00211 const bool now=true
00215 )
00216 throw(SocketException);
00217
00218
00219 Socket
00220 (
00221 const char *host,
00222 const int port,
00223 const bool now=true
00224 )
00225 throw(SocketException);
00226
00227
00228 Socket( const int port, const bool now=true )
00229 throw(SocketException);
00230
00231
00237 virtual ~Socket();
00238
00239
00247 virtual void connect() throw(SocketException);
00248
00249
00272 virtual const ssize_t readLine
00273 (
00274 std::string& buffer,
00277 const std::string& delim,
00279 int * const error=0,
00284 const long int msec=0
00291 )
00292 throw( SocketException );
00293
00294
00310 virtual const ssize_t read
00311 (
00312 char * const buffer,
00314 const int buflen,
00316 int * const error=0,
00321 const long msec=0
00328 )
00329 throw( SocketException );
00330
00331
00337 virtual const ssize_t receive
00338 (
00339 char * const buffer,
00340 const int buflen,
00341 const long int msec=0,
00342 int * const error=0
00343 )
00344 throw( SocketException );
00345
00346
00359 virtual const ssize_t write
00360 (
00361 const char * buffer,
00363 const long buflen,
00365 int * const error=0,
00370 const long int msec=0
00377 )
00378
00379 throw( SocketException );
00380
00381
00387 virtual const ssize_t send
00388 (
00389 const char * buffer,
00390 const long buflen,
00391 const long int msec=0,
00392 int * const error=0
00393 )
00394 throw( SocketException );
00395
00396
00403 const socket_t getHandle() const;
00404
00405
00420 std::iostream& get_iostream() throw(SocketException);
00421
00422
00429 static Socket* create
00430 (
00431 const socket_t s
00432 );
00433
00434
00441 inline const struct sockaddr_in& get_addr() const { return _host; }
00442
00443
00454 virtual const bool isError() const;
00455
00456
00465 inline const std::string& getError() const { return _errstr; }
00466
00467
00488 virtual const bool isReadable
00489 (
00490 long int * msec=0,
00500 int * const error=0
00504 ) const;
00505
00506
00514 virtual const bool isWritable
00515 (
00516 long int * msec=0,
00526 int * const error=0
00530 ) const;
00531
00532
00538 inline operator std::ostream&() { return get_iostream(); }
00539
00540
00546 inline operator std::istream&() { return get_iostream(); }
00547
00548
00558 virtual const bool set_blocking_on();
00559
00560
00572 virtual const bool set_blocking_off();
00573
00574
00584 virtual const int getSockOpt
00585 (
00586 const int level,
00587 const int op_name,
00588 char* buffer,
00589 int* buflen
00590 ) const;
00591
00592
00609 std::ostream* getLogger() const;
00610
00611
00619 std::ostream* getLocalLogger() const;
00620
00621
00626 void setLocalLogger
00627 (
00628 std::ostream* os
00629 ) const;
00630
00631
00641 void closeLocalLogger() const;
00642
00643
00655 static std::ostream* getGlobalLogger();
00656
00657
00670 static void setGlobalLogger( std::ostream* os );
00671
00672
00682 static void closeGlobalLogger();
00683
00684
00685
00686 class DateTime {};
00687
00688
00689 protected:
00690
00694 Socket();
00695
00696
00705 const bool isAvailable
00706 (
00707 fd_set* rd,
00710 fd_set* wr,
00713 long int * msec=0,
00717 int * error=0
00720 ) const;
00721
00722
00723 socket_t _sockfd;
00724 struct sockaddr_in _host;
00725 int _port;
00726 std::iostream* _iostream;
00727 mutable bool _error;
00728 mutable std::string _errstr;
00729 bool _is_connected;
00731
00732 bool _is_bound;
00733
00734 mutable std::ostream* _llogr;
00735 static std::ostream* _glogr;
00738 private:
00739
00740 friend class ServerSocket;
00742
00743 inline void set_bound( const bool val ) { _is_bound = val; }
00744
00751 void invalid_host
00752 (
00753 const char *
00754 ) const throw( SocketException );
00755
00756
00763 socket_t make_socket
00764 (
00765 const char* name,
00766 const int port,
00767 const bool now
00768 )
00769 throw( SocketException );
00770
00771
00778 unsigned long resolve_name
00779 (
00780 const char*
00781 );
00782
00783
00787 void bind_address
00788 (
00789 struct sockaddr_in* inout_address,
00790 unsigned long in_IP,
00791 const int in_port
00792 );
00793
00794
00802 void ignore_epipe
00803 (
00804 const bool
00805 );
00806
00807
00812 mutable CriticalSection _write_csect;
00813
00814
00819 mutable CriticalSection _read_csect;
00820
00821
00826 mutable CriticalSection _csect;
00827
00828
00829 private:
00830
00831 Socket( const Socket& );
00832 Socket& operator=(const Socket&);
00833
00834 };
00835
00836 };
00837
00838
00845 std::ostream& operator<<( std::ostream& os, const cbits::Socket::DateTime& dt );
00846
00847
00848 #ifdef SOCKET_GET_THREADID
00849 #undef SOCKET_GET_THREADID
00850 #endif
00851
00852 #if defined(USE_PTHREADS)
00853 #include <pthread.h>
00854 #define SOCKET_GET_THREADID (unsigned long)pthread_self()
00855 #endif
00856
00857 #if defined(WIN32)
00858 #define SOCKET_GET_THREADID (unsigned long)GetCurrentThreadId()
00859 #endif
00860
00861
00866 #define elog *(this->getLogger())<<"ERROR "<<cbits::Socket::DateTime()<<" {"<<SOCKET_GET_THREADID<<"} "<<__FILE__<<" [line "<<__LINE__<<"]: "
00867
00868 #ifdef TRACEON
00869
00873 #define trace \
00874 do \
00875 {\
00876 *(this->getLogger())<<"TRACE "<<cbits::Socket::DateTime<<" {"<<SOCKET_GET_THREADID<<"} "<<__FILE__<<" [line "<<__LINE__<<"]"<<std::endl; \
00877 }while(false)
00878 #else
00879 #define trace \
00880 do \
00881 {\
00882 \
00883 }while(false)
00884 #endif
00885
00886 #endif
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917