00001
00014
00015
00016 #include <errno.h>
00017 #include "ConnectableSocket.h"
00018 #include "SystemCall.h"
00019
00020
00022
00023
00024
00025 std::ostream& ConnectableSocket::operator<<( std::ostream& stream) const
00026 {
00027 stream << "ConnectableSocket( ";
00028 if ( isOpen() ) {
00029 stream << getDescriptor() << ", ";
00030 if ( isConnected() )
00031 peerAddress().operator <<(stream);
00032 else
00033 stream << "connection is not defined";
00034 }
00035 else {
00036 stream << "connection is not currently opened";
00037 }
00038
00039 stream << " )";
00040 return stream;
00041 }
00042
00043
00044
00045 bool ConnectableSocket::isEof() const
00046 {
00047 return ( flags_ & state_eof ) != 0;
00048 }
00049
00050
00051
00052 bool ConnectableSocket::eventOnEof() const
00053 {
00054 return ( flags_ & state_raise_event ) != 0;
00055 }
00056
00057
00058
00059 void ConnectableSocket::eventOnEof( bool flag )
00060 {
00061 if ( flag )
00062 flags_ |= state_raise_event;
00063 else
00064 flags_ &= ~state_raise_event;
00065 }
00066
00067
00068 bool ConnectableSocket::isOk() const
00069 {
00070 return isOpen() && ( ( flags_ & state_failed ) == 0 );
00071 }
00072
00073
00074
00075 bool ConnectableSocket::isGood() const
00076 {
00077 return isOk() && !isEof();
00078 }
00079
00080
00081
00082 void ConnectableSocket::clear()
00083 {
00084 flags_ &= state_raise_event;
00085 }
00086
00087
00088
00089 bool ConnectableSocket::getFlags( short mask ) const
00090 {
00091 return ( flags_ & mask ) == mask;
00092 }
00093
00094
00095
00096 ConnectableSocket::ConnectableSocket( SOCKET descriptor ) : Socket( descriptor )
00097 {
00098 }
00099
00100
00101
00102 ConnectableSocket::ConnectableSocket(int type,int domain,int protocol) : Socket(type,domain,protocol)
00103 {
00104 }
00105
00106
00107
00108 void ConnectableSocket::connectTo( const SocketAddress& address )
00109 {
00110 sockaddr_in in = address.operator sockaddr_in();
00111 connectTo(reinterpret_cast<sockaddr*>(&in),sizeof(sockaddr));
00112 }
00113
00114
00115
00116 void ConnectableSocket::connectTo( sockaddr* address, int size )
00117 {
00118 int result;
00119 SOCKET_CALL_3( result=(int),::connect,getDescriptor(),address,size)
00120 if ( result >= 0 )
00121 clear();
00122 }
00123
00124
00125
00126
00127
00128 int ConnectableSocket::receiveFrom(SocketAddress& address,void* buffer,int bytes)
00129 {
00130 int result = -1 ;
00131
00132 #ifdef _MSC_VER
00133 int length = sizeof( sockaddr );
00134 #else
00135 socklen_t length = sizeof( sockaddr );
00136 #endif
00137
00138 if ( isOk() ) {
00139 SOCKET_CALL_6(result = (int),::recvfrom,getDescriptor(),(char*) buffer,
00140 bytes,0,(sockaddr*) &(address.operator sockaddr_in()),&length)
00141
00142 if ( result < 0 )
00143 flags_ |= state_failed;
00144 }
00145 return result;
00146 }
00147
00148
00149
00150 bool ConnectableSocket::isConnected() const
00151 {
00152 bool connected = true;
00153 try {
00154 peerAddress();
00155 }
00156 catch ( NetworkException& ) {
00157 connected = false;
00158 }
00159 return connected;
00160 }
00161
00162
00163
00164 int ConnectableSocket::write( const void* buffer, int bytes )
00165 {
00166 int result = -1;
00167 if ( !( flags_ & state_failed ) ) {
00168 result = ::send(socketHandle,reinterpret_cast<const char*>(buffer),bytes,0);
00169 if (result < 0) {
00170 flags_ |= state_failed;
00171 NetworkException::throwNetworkException(NetworkException::write_failed,socket_error);
00172 }
00173 else {
00174 flags_ &= ~state_eof;
00175 }
00176 }
00177
00178 return result;
00179 }
00180
00181
00182
00183
00184 int ConnectableSocket::read( void* buffer, int bytes )
00185 {
00186 int result = -1;
00187 if ( !( flags_ & state_failed ) ) {
00188 result = ::recv(socketHandle,reinterpret_cast<char*>(buffer),bytes,0);
00189 if (result < 0) {
00190 flags_ |= state_failed;
00191 NetworkException::throwNetworkException(NetworkException::read_failed,socket_error);
00192 }
00193 else if ( !result && !(flags_ & state_eof) ) {
00194 flags_ |= state_eof;
00195 if (( flags_ & state_raise_event) == state_raise_event)
00196 NetworkException::throwNetworkException(NetworkException::eof_encountered);
00197 }
00198 }
00199 return result;
00200 }
00201
00202
00203
00204
00205 SocketAddress ConnectableSocket::peerAddress() const
00206 {
00207 SocketAddress address;
00208 #ifdef _MSC_VER
00209 int length = sizeof( sockaddr );
00210 #else
00211 socklen_t length = sizeof( sockaddr );
00212 #endif
00213 int dummy = 0;
00214 SOCKET_CALL_3(dummy =,::getpeername,getDescriptor(),
00215 reinterpret_cast<sockaddr*>(&(address.operator sockaddr_in())),&length)
00216 return address;
00217 }