00001 #include <iostream>
00002 #include <stdio.h>
00003
00004
00005 #include "SysPlusPlus/syscall.h"
00006 #include "SysPlusPlus/syslib.h"
00007 #include "SysPlusPlus/Tools.h"
00008 #include "ComPlusPlus/Poll.h"
00009 #include "ComPlusPlus/SocketTcp.h"
00010 #include "SysPlusPlus/GenCfg.h"
00011 #include "SysPlusPlus/ComException.h"
00012
00016 void compp::SocketTcp::NewTcpSocket() {
00017
00018 this->fd = syspp::Call::Socket ( PF_INET, SOCK_STREAM, 0 );
00019 if ( this->fd == -1 ) {
00020 throw syspp::ComException("Panic: Cannot create socket!");
00021 }
00022 IsOpen=false;
00023 FdClosed=false;
00024
00025 Async = false;
00026 AsyncConnect = false;
00027 OptTcpNoDelay = false;
00028 Backlog = 5 ;
00029
00030 }
00031
00036 compp::SocketTcp::~SocketTcp() {
00037
00038 if ( this->fd == -1 )
00039 return;
00040 if ( this->FD_IsAttached() )
00041 this->Shutdown ();
00042
00043 }
00044
00045
00050 compp::SocketTcp::SocketTcp( unsigned int buffsz ) : Socket ( buffsz ) {
00051
00052 NewTcpSocket();
00053 compp::GenCfg * Cfg = (compp::GenCfg*) compp::GenCfg::Instance();
00054 SetOptTcpNoDelay( Cfg->GetCommOptTcpNoDelay()) ;
00055 SetBacklog(Cfg->GetCommBacklog()) ;
00056
00057 }
00058
00059
00064 compp::SocketTcp::SocketTcp ( struct sockaddr_in *saddr, int len, int fd, unsigned int readaheadbufsz ) : Socket (readaheadbufsz) {
00065
00066 compp::GenCfg * Cfg = (compp::GenCfg*) compp::GenCfg::Instance();
00067 SetOptTcpNoDelay( Cfg->GetCommOptTcpNoDelay()) ;
00068 SetBacklog(Cfg->GetCommBacklog()) ;
00069
00070 this->fd = fd;
00071 this->IsOpen=true;
00072 this->FdClosed=false;
00073
00074 std::string s;
00075 s= inet_ntoa ( (const in_addr&) saddr->sin_addr.s_addr) ;
00076 SocketAddress = s ;
00077
00078 char ctmp[60];
00079 unsigned short si;
00080 si = ntohs( saddr->sin_port);
00081 sprintf ( ctmp, "%u", si );
00082
00083 s+=":";
00084 s+= ctmp;
00085 ContextString = s;
00086
00087 SocketPort = si;
00088 }
00089
00094 void compp::SocketTcp::Close() {
00095
00096 if ( this->fd == -1 ) {
00097 return ;
00098 }
00099 syspp::Call::Close ( this->fd );
00100 this->fd = -1;
00101 this->IsOpen=false;
00102 this->FdClosed = true;
00103
00104 }
00105
00113 void compp::SocketTcp::Shutdown( int method ) {
00114
00115 syspp::Call::Shutdown ( this->fd, method );
00116 Close();
00117
00118 }
00119
00127 compp::SocketTcp::SocketTcp(const std::string & Addr, int port) {
00128
00129 compp::GenCfg * Cfg = (compp::GenCfg*) compp::GenCfg::Instance();
00130 SetOptTcpNoDelay( Cfg->GetCommOptTcpNoDelay()) ;
00131 SetOptAsyncConnect( Cfg->GetCommOptAsyncConnect()) ;
00132 SetOptAsync(Cfg->GetCommOptAsync()) ;
00133 SetBacklog(Cfg->GetCommBacklog()) ;
00134
00135 NewTcpSocket();
00136 this->Bind ( Addr, port );
00137 this->Listen();
00138 }
00147 compp::SocketTcp::SocketTcp( int port) {
00148
00149 compp::GenCfg * Cfg = (compp::GenCfg*) compp::GenCfg::Instance();
00150 SetOptTcpNoDelay( Cfg->GetCommOptTcpNoDelay()) ;
00151 SetOptAsyncConnect( Cfg->GetCommOptAsyncConnect()) ;
00152 SetOptAsync(Cfg->GetCommOptAsync()) ;
00153 SetBacklog(Cfg->GetCommBacklog()) ;
00154
00155 NewTcpSocket();
00156 this->Bind ( SocketANYHOST, port );
00157 this->Listen();
00158 }
00159
00160
00165 void compp::SocketTcp::Listen ( const int backlog ) {
00166
00167 if ( backlog < 1 || backlog > 10000 ) {
00168
00169
00170 ;
00171 }
00172
00173 if ( syspp::Call::Listen ( this->fd, backlog ) != 0 ) {
00174 throw syspp::ComException ( "compp::SocketTcp::Listen. Listen() failed");
00175 }
00176
00177 }
00178
00182 void compp::SocketTcp::Listen ( ) {
00183
00184
00185
00186 Listen ( GetBacklog() );
00187 }
00188
00193 void compp::SocketTcp::Bind ( const std::string & addr, int port) {
00194 struct sockaddr_in ad;
00195 in_addr_t adv4;
00196
00197
00198 struct hostent *hent;
00199
00200 (void) memset((void *) &adv4, 0, sizeof (adv4));
00201
00202 if ( addr == SocketANYHOST ) {
00203 memset ( & ad.sin_addr ,0, sizeof (ad.sin_addr));
00204 } else {
00205 if ( INADDR_NONE == ( adv4 = inet_addr ( addr.c_str() ))) {
00206 if ( this->GetUseDNS() ) {
00207 if (NULL == (hent = syspp::Lib::Gethostbyname (addr.c_str() ))) {
00208
00209
00210 throw syspp::ComException ( "compp::SocketTcp:Bind Cannot Resolve Hostname " );
00211 } else {
00212 std::memmove( &(adv4), *hent->h_addr_list , sizeof(adv4));
00213 ad.sin_addr.s_addr = adv4;
00214 }
00215 }
00216 } else {
00217 ad.sin_addr.s_addr = adv4;
00218 }
00219 }
00220 ad.sin_family = AF_INET;
00221 ad.sin_port = htons(port);
00222
00223 if ( -1 == syspp::Call::Bind( this->fd, (struct sockaddr* )&ad, sizeof(ad))) {
00224
00225
00226 throw syspp::ComException ( "compp::SocketTcp::Bind Cannot Bind " );
00227 }
00228 this->SocketPort = port;
00229 State = Bound;
00230
00231
00232 }
00233
00237 void compp::SocketTcp::Bind ( const int port ) {
00238
00239 this->Bind ( SocketANYHOST, port );
00240
00241 }
00242
00246 bool compp::SocketTcp::Connect( const std::string &addr, const int port ){
00247
00248 if ( this->fd == -1 )
00249 NewTcpSocket();
00250
00251 if (this->GetOptAsyncConnect()) {
00252 SetOptNonBlocking();
00253 }
00254
00255 bool retval ;
00256 if ( false == ( retval = _Connect( addr, port ) ) ) {
00257 return retval;
00258 }
00259
00260 this->SetSockOptTcpNoDelay ( this->GetOptTcpNoDelay() );
00261
00262 if (this->GetOptSync() ) {
00263 SetOptNonBlocking();
00264 }
00265
00266 IsOpen=true;
00267 FdClosed=false;
00268 this->ReadAheadBufferSize = 0;
00269 this->ReadAheadBufferIndex = 0;
00270
00271 return retval;
00272 }
00273
00274
00282 bool compp::SocketTcp::SetSockOptTcpNoDelay ( bool yesno ) {
00283 int opt;
00284
00285 if ( yesno == true )
00286 opt = 1;
00287 else
00288 opt = 0;
00289
00290 if ( 0 != syspp::Call::Setsockopt (this->fd, IPPROTO_TCP, TCP_NODELAY, (void*)&opt, sizeof(opt) )) {
00291 return false;
00292 }
00293 return true;
00294
00295 }
00296
00300 bool compp::SocketTcp::SetSockOptTCP_MAXSEG ( int val ) {
00301 #ifndef TCP_MAXSEG
00302 return false;
00303 #else
00304
00305 int opt = val;
00306
00307
00308 if ( 0 != syspp::Call::Setsockopt (this->fd, IPPROTO_TCP, TCP_MAXSEG, (void*)&opt, sizeof(opt) )) {
00309 return false;
00310 }
00311
00312 return true;
00313 #endif
00314
00315 }
00316
00317
00318
00328 compp::SocketTcp* compp::SocketTcp::Accept ( void ) {
00329
00330 struct sockaddr_in addr_in;
00331
00332 int l;
00333 int rets;
00334 compp::SocketTcp *returnSocket;
00335
00336 this->SetSockOptLinger (this->GetLingerTime());
00337 l = sizeof ( addr_in );
00338 if ( (rets = syspp::Call::Accept ( this->fd, (struct sockaddr *) &addr_in, &l )) == -1 ) {
00339 throw syspp::ComException ( "compp::SocketTcp::Accept(). Accept() failed.");
00340 }
00341
00342
00343 returnSocket = new SocketTcp ( &addr_in, (int)l, rets, ReadAheadBufferTotalSize ) ;
00344 returnSocket->SetSockOptLinger (this->GetLingerTime());
00345 returnSocket->SetSockOptTcpNoDelay ( GetOptTcpNoDelay() );
00346 returnSocket->SetReadAhead ( this->ReadAhead );
00347
00348 return returnSocket;
00349 }
00350
00351
00352
00356 void compp::SocketTcp::SetOptTcpNoDelay( bool val) {
00357 OptTcpNoDelay = val;
00358 }
00359
00360 bool compp::SocketTcp::GetOptTcpNoDelay() const {
00361 return OptTcpNoDelay;
00362 }
00363
00367 void compp::SocketTcp::SetOptAsyncConnect( bool val) {
00368 AsyncConnect = val;
00369 }
00370
00374 bool compp::SocketTcp::GetOptAsyncConnect() const{
00375 return AsyncConnect;
00376 }
00377
00381 void compp::SocketTcp::SetOptAsync(bool val) {
00382 Async = val;
00383 }
00384
00385
00389 bool compp::SocketTcp::GetOptSync() const{
00390 return Async;
00391 }
00392
00396 void compp::SocketTcp::SetBacklog(int val) {
00397 Backlog = val;
00398 }
00399
00400 bool compp::SocketTcp::GetBacklog() const{
00401 return Backlog;
00402 }
00403
00404
00405 const std::string compp::SocketTcp::GetPeerSockIPAddr() const {
00406
00407 if ( fd == -1 ) {
00408 throw syspp::ComException("Cannot get peer from not connected socket.");
00409 }
00410
00411 struct sockaddr_in saddr;
00412 socklen_t len = sizeof ( saddr ) ;
00413 if ( 0 != getpeername(fd, (struct sockaddr *) &saddr, &len)) {
00414 throw syspp::ComException("Cannot get peer address");
00415 }
00416
00417 std::string retval ;
00418 retval = inet_ntoa ( (const in_addr&) saddr.sin_addr.s_addr) ;
00419
00420 return retval;
00421 }
00422
00423 const unsigned short compp::SocketTcp::GetPeerSockPort() const {
00424
00425 if ( fd == -1 ) {
00426 throw syspp::ComException("Cannot get peer from not connected socket.");
00427 }
00428
00429 struct sockaddr_in saddr;
00430 socklen_t len = sizeof ( saddr ) ;
00431 if ( 0 != getpeername(fd, (struct sockaddr *) &saddr, &len)) {
00432 throw syspp::ComException("Cannot get peer socket address");
00433 }
00434
00435 std::string retval ;
00436 retval = inet_ntoa ( (const in_addr&) saddr.sin_addr.s_addr) ;
00437 return ntohs(saddr.sin_port) ;
00438 }
00439
00440
00441 const std::string compp::SocketTcp::GetSockIPAddr() const {
00442
00443 if ( fd == -1 ) {
00444 throw syspp::ComException("Cannot get address from not connected socket.");
00445 }
00446
00447 struct sockaddr_in saddr;
00448 socklen_t len = sizeof ( saddr ) ;
00449 if ( 0 != getsockname(fd, (struct sockaddr *) &saddr, &len)) {
00450 throw syspp::ComException("Cannot get socket address");
00451 }
00452
00453 std::string retval ;
00454 retval = inet_ntoa ( (const in_addr&) saddr.sin_addr.s_addr) ;
00455
00456 return retval;
00457 }
00458
00459 const unsigned short compp::SocketTcp::GetSockPort() const {
00460
00461 if ( fd == -1 ) {
00462 throw syspp::ComException("Cannot get address from not connected socket.");
00463 }
00464
00465 struct sockaddr_in saddr;
00466 socklen_t len = sizeof ( saddr ) ;
00467 if ( 0 != getsockname(fd, (struct sockaddr *) &saddr, &len)) {
00468 throw syspp::ComException("Cannot get socket address");
00469 }
00470
00471 std::string retval ;
00472 retval = inet_ntoa ( (const in_addr&) saddr.sin_addr.s_addr) ;
00473 return ntohs(saddr.sin_port) ;
00474 }
00475
00476
00477