00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <iostream>
00024 #include <unistd.h>
00025 #include <sys/socket.h>
00026 #include <netinet/in.h>
00027 #include <netinet/tcp.h>
00028 #include <errno.h>
00029 #include <limits.h>
00030 #include <fcntl.h>
00031 #include <sys/types.h>
00032 #include <poll.h>
00033
00034 #ifdef RIO_DEBUG2
00035 #include <sys/time.h>
00036 #include <time.h>
00037 #endif
00038
00039
00040 #include <sys/syscall.h>
00041
00042
00043 #include "RioError.h"
00044 #include "NetTcp.h"
00045 #include "NetInterface.h"
00046
00047
00048 #ifdef RIO_DEBUG_FILE
00049 #define TCPCONNECTIONLOG m_NetTcp->m_log
00050 #define TCPCONNECTIONLOGEST TcpConnection->m_NetTcp->m_log
00051 #define TCPLOG m_log
00052 #define TCPLOGEST NetTcp->m_log
00053 #else
00054 #define TCPCONNECTIONLOG RioErr
00055 #define TCPCONNECTIONLOGEST RioErr
00056 #define TCPLOG RioErr
00057 #define TCPLOGEST RioErr
00058 #endif
00059
00060
00061
00062
00063
00064
00065
00066 CTcpConnection::CTcpConnection( CNetTcp *NetTcp, bool ServerInstance )
00067 {
00068
00069 m_NetTcp = NetTcp;
00070
00071 #ifdef RIO_DEBUG1
00072 TCPCONNECTIONLOG << "[CTcpConnection - Construtor] Start" << endl;
00073 #endif
00074
00075
00076 m_NetTcp = NetTcp;
00077 m_ServerInstance = ServerInstance;
00078 m_IP = 0;
00079 m_Port = 0;
00080 m_Socket = 0;
00081 m_LastUseTime = 0;
00082 m_isClosingSocket = false;
00083 m_LogRotation = NULL;
00084 m_isAborted = false;
00085 m_ConnectionTimeOut = 0;
00086 m_SentSignal = false;
00087 m_PollSocket = 0;
00088 memset( &m_PollSocketAddr, 0, sizeof( m_PollSocketAddr ) );
00089 #ifdef RIO_DEBUG2
00090 m_ReceiveCount = 0;
00091 m_SendCount = 0;
00092 #endif
00093
00094
00095
00096 m_Initialized = false;
00097
00098
00099
00100
00101 pthread_mutex_init( &m_Mutex, NULL );
00102 pthread_cond_init( &m_Cond, NULL );
00103
00104 #ifdef RIO_DEBUG1
00105 TCPCONNECTIONLOG << "[CTcpConnection - Construtor] Finish" << endl;
00106 #endif
00107 }
00108
00109
00110 CTcpConnection::~CTcpConnection()
00111 {
00112 #ifdef RIO_DEBUG1
00113 TCPCONNECTIONLOG << "[CTcpConnection - Destrutor] Start" << endl;
00114 #endif
00115
00116
00117 pthread_mutex_destroy( &m_Mutex );
00118
00119
00120
00121 pthread_cond_destroy( &m_Cond );
00122
00123 #ifdef RIO_DEBUG1
00124 TCPCONNECTIONLOG << "[CTcpConnection - Destrutor] Finish" << endl;
00125 #endif
00126 }
00127
00128
00129 RioResult CTcpConnection::GetSendData( char **Data, unsigned int *DataSize,
00130 void **Param )
00131 {
00132 #ifdef RIO_DEBUG1
00133 TCPCONNECTIONLOG << "[CTcpConnection - GetSendData] Start" << endl;
00134 #endif
00135
00136
00137 pthread_mutex_lock( &m_Mutex );
00138
00139
00140
00141 if( m_SendQueue.empty() )
00142 {
00143
00144 pthread_mutex_unlock( &m_Mutex );
00145
00146
00147
00148 #ifdef RIO_DEBUG2
00149 TCPCONNECTIONLOG << "CTcpConnection::GetSendData a fila de envio do "
00150 << "socket com a ID " << m_Socket << " esta vazia!"
00151 << endl;
00152 #endif
00153
00154 *Data = NULL;
00155 *DataSize = 0;
00156 *Param = NULL;
00157
00158 #ifdef RIO_DEBUG1
00159 TCPCONNECTIONLOG << "[CTcpConnection - GetSendData] Finish1" << endl;
00160 #endif
00161
00162 return ERROR_TCPCONNECTION + ERROR_UNEXPECTED;
00163 }
00164 else
00165 {
00166 #ifdef RIO_DEBUG2
00167 TCPCONNECTIONLOG << "CTcpConnection::GetSendData tentando retirar os "
00168 << "dados a serem enviados pelo socket com a ID "
00169 << m_Socket << ". Tamanho da fila e de "
00170 << m_SendQueue.size() << "." << endl;
00171 #endif
00172
00173
00174
00175 *Data = m_SendQueue.front().Data;
00176 *DataSize = m_SendQueue.front().DataSize;
00177 *Param = m_SendQueue.front().Param;
00178
00179 m_SendQueue.pop();
00180
00181 #ifdef RIO_DEBUG2
00182 TCPCONNECTIONLOG << "CTcpConnection::GetSendData dados a serem "
00183 << "enviados pelo socket com a ID " << m_Socket
00184 << " retirados com sucesso. Tamanho da fila e agora "
00185 << "de " << m_SendQueue.size() << "." << endl;
00186 #endif
00187 }
00188
00189
00190 pthread_mutex_unlock( &m_Mutex );
00191
00192 #ifdef RIO_DEBUG1
00193 TCPCONNECTIONLOG << "[CTcpConnection - GetSendData] Finish2" << endl;
00194 #endif
00195
00196 return S_OK;
00197 }
00198
00199
00200 RioResult CTcpConnection::ReceiveStreamData( char **Data,
00201 unsigned int *DataSize )
00202 {
00203
00204 ssize_t BytesReceived;
00205
00206
00207 unsigned int NetDataSize;
00208
00209 #ifdef RIO_DEBUG1
00210 TCPCONNECTIONLOG << "[CTcpConnection - ReceiveStreamData] Start" << endl;
00211 #endif
00212
00213
00214 struct in_addr ip;
00215
00216 #ifdef RIO_DEBUG2
00217
00218
00219 struct timeval Start, End;
00220 unsigned int DiffTime;
00221 #endif
00222
00223
00224 ip.s_addr = m_IP;
00225
00226
00227 m_LastUseTime = time( NULL );
00228
00229 #ifdef RIO_DEBUG2
00230
00231 gettimeofday( &Start, NULL );
00232 #endif
00233
00234
00235 BytesReceived = recv( m_Socket, &NetDataSize, sizeof( unsigned int ),
00236 TCP_FLAGS_RECEIVE );
00237
00238 #ifdef RIO_DEBUG2
00239
00240 gettimeofday( &End, NULL );
00241 DiffTime = ( End.tv_sec - Start.tv_sec ) * 1000 +
00242 ( End.tv_usec - Start.tv_usec ) / 1000;
00243 TCPCONNECTIONLOG << "CTcpConnection::ReceiveStreamData tempo para executar "
00244 << "a funcao recv (tamanho) para o socket com a ID "
00245 << m_Socket << ": " << DiffTime << " ms." << endl;
00246 #endif
00247
00248
00249 if( BytesReceived < 0 )
00250 {
00251 #ifdef RIO_DEBUG2
00252 TCPCONNECTIONLOG << "CTcpConnection::ReceiveStreamData " << errno
00253 << " (" << strerror( errno ) << ") ao receber o "
00254 << "tamanho do endereco IP " << inet_ntoa( ip )
00255 << " e a porta " << ntohs( m_Port ) << " a partir "
00256 << "do socket com a ID " << m_Socket << "." << endl;
00257 #endif
00258
00259 *Data = NULL;
00260 *DataSize = 0;
00261
00262 #ifdef RIO_DEBUG1
00263 TCPCONNECTIONLOG << "[CTcpConnection - ReceiveStreamData] Finish1"
00264 << endl;
00265 #endif
00266
00267 return ERROR_TCPCONNECTION + ERROR_SOCKET_RECEIVE;
00268 }
00269 else if( BytesReceived != sizeof( unsigned int ) )
00270 {
00271 *Data = NULL;
00272 *DataSize = 0;
00273
00274 if( BytesReceived == 0 )
00275 {
00276
00277
00278
00279
00280 #ifdef RIO_DEBUG2
00281 TCPCONNECTIONLOG << "[CTcpConnection] Tentamos receber dados pela "
00282 << "conexao TCP do IP " << inet_ntoa( ip )
00283 << " e a porta " << ntohs( m_Port ) << ", mas "
00284 << "nenhum dado chegou pelo socket com a ID "
00285 << m_Socket << ". Logo, esta conexao TCP sera "
00286 << "entao fechada!" << endl;
00287 #endif
00288
00289 #ifdef RIO_DEBUG1
00290 TCPCONNECTIONLOG << "[CTcpConnection - ReceiveStreamData] Finish2"
00291 << endl;
00292 #endif
00293
00294
00295
00296
00297 return S_OK;
00298 }
00299 else
00300 {
00301
00302
00303
00304 #ifdef RIO_DEBUG2
00305 TCPCONNECTIONLOG << "CTcpConnection::ReceiveStreamData nao foram "
00306 << "recebidos bytes suficientes ao receber o "
00307 << "tamanho dos dados do endereco IP "
00308 << inet_ntoa( ip ) << " e a porta "
00309 << ntohs( m_Port ) << " pelo socket com a ID "
00310 << m_Socket << ". Foram recebidos "
00311 << BytesReceived << " bytes, mas deveriam ser "
00312 << sizeof( unsigned int ) << " bytes." << endl;
00313 #endif
00314
00315 #ifdef RIO_DEBUG1
00316 TCPCONNECTIONLOG << "[CTcpConnection - ReceiveStreamData] Finish3"
00317 << endl;
00318 #endif
00319
00320 return ERROR_TCPCONNECTION + ERROR_SOCKET_RECEIVE;
00321 }
00322 }
00323
00324
00325 *DataSize = ntohl( NetDataSize );
00326
00327
00328
00329 if( DataSize > 0 )
00330 {
00331
00332 try
00333 {
00334 #ifdef RIO_DEBUG2
00335 TCPCONNECTIONLOG << "CTcpConnection::ReceiveStreamData tentando "
00336 << "alocar um vetor com " << *DataSize << " bytes "
00337 << "para receber dados do socket com a ID "
00338 << m_Socket << "." << endl;
00339 #endif
00340
00341 *Data = new char[ *DataSize ];
00342
00343 #ifdef RIO_DEBUG2
00344 TCPCONNECTIONLOG << "CTcpConnection::ReceiveStreamData vetor com "
00345 << *DataSize << " bytes alocado com sucesso para "
00346 << "receber dados do socket com a ID " << m_Socket
00347 << "." << endl;
00348 #endif
00349 }
00350 catch( bad_alloc &ba )
00351 {
00352 #ifdef RIO_DEBUG2
00353 TCPCONNECTIONLOG << "CTcpConnection::ReceiveStreamData memoria "
00354 << "insuficiente para criar o buffer com "
00355 << *DataSize << " bytes para receber os dados "
00356 << "do endereco IP " << inet_ntoa( ip )
00357 << " e a porta " << ntohs( m_Port )
00358 << " pelo socket com a ID " << m_Socket
00359 << " (bad_alloc, error = " << ba.what() << ")."
00360 << endl;
00361 #endif
00362
00363 *DataSize = 0;
00364 *Data = NULL;
00365
00366 #ifdef RIO_DEBUG1
00367 TCPCONNECTIONLOG << "[CTcpConnection - ReceiveStreamData] Finish4"
00368 << endl;
00369 #endif
00370
00371 return ERROR_TCPCONNECTION + ERROR_MEMORY;
00372
00373 }
00374
00375 #ifdef RIO_DEBUG2
00376
00377 gettimeofday( &Start, NULL );
00378 #endif
00379
00380
00381 BytesReceived = recv( m_Socket, *Data, *DataSize, TCP_FLAGS_RECEIVE );
00382
00383 #ifdef RIO_DEBUG2
00384
00385 gettimeofday( &End, NULL );
00386 DiffTime = ( End.tv_sec - Start.tv_sec ) * 1000 +
00387 ( End.tv_usec - Start.tv_usec ) / 1000;
00388 TCPCONNECTIONLOG << "CTcpConnection::ReceiveStreamData tempo para "
00389 << "executar a funcao recv (dados) para o socket com "
00390 << "a ID " << m_Socket << ": " << DiffTime << " ms."
00391 << endl;
00392 #endif
00393
00394
00395 if( BytesReceived < 0 )
00396 {
00397 #ifdef RIO_DEBUG2
00398 TCPCONNECTIONLOG << "CTcpConnection::ReceiveStreamData erro "
00399 << errno << " (" << strerror( errno ) << ") ao "
00400 << "receber os dados do endereco IP "
00401 << inet_ntoa( ip ) << " e a porta "
00402 << ntohs( m_Port ) << "pelo socket com a ID "
00403 << m_Socket << "." << endl;
00404 #endif
00405
00406
00407 delete[] *Data;
00408
00409 *Data = NULL;
00410 *DataSize = 0;
00411
00412 #ifdef RIO_DEBUG1
00413 TCPCONNECTIONLOG << "[CTcpConnection - ReceiveStreamData] Finish5"
00414 << endl;
00415 #endif
00416
00417 return ERROR_TCPCONNECTION + ERROR_SOCKET_RECEIVE;
00418 }
00419 else if( ( ( unsigned int ) BytesReceived ) != *DataSize )
00420 {
00421 #ifdef RIO_DEBUG2
00422 TCPCONNECTIONLOG << "CTcpConnection::ReceiveStreamData os dados "
00423 << "do endereco IP " << inet_ntoa( ip ) << " e a "
00424 << "porta " << ntohs( m_Port ) << "pelo "
00425 << "socket com a ID " << m_Socket << " foram "
00426 << "recebidos parcialmente, pois somente chegaram "
00427 << BytesReceived << " bytes do total de "
00428 << DataSize << "bytes." << endl;
00429 #endif
00430
00431
00432 delete[] *Data;
00433
00434 *Data = NULL;
00435 *DataSize = 0;
00436
00437 #ifdef RIO_DEBUG1
00438 TCPCONNECTIONLOG << "[CTcpConnection - ReceiveStreamData] Finish6"
00439 << endl;
00440 #endif
00441
00442 return ERROR_TCPCONNECTION + ERROR_SOCKET_RECEIVE;
00443 }
00444 }
00445
00446 #ifdef RIO_DEBUG2
00447
00448 m_ReceiveCount++;
00449
00450 TCPCONNECTIONLOG << "CTcpConnection::ReceiveStreamData foram recebidos "
00451 << *DataSize << " bytes com sucesso pelo socket com a ID "
00452 << m_Socket << "." << endl;
00453 #endif
00454
00455 #ifdef RIO_DEBUG1
00456 TCPCONNECTIONLOG << "[CTcpConnection - ReceiveStreamData] Finish7"
00457 << endl;
00458 #endif
00459
00460 return S_OK;
00461 }
00462
00463
00464 RioResult CTcpConnection::SendStreamData( unsigned int *DataSize, void **Param )
00465 {
00466
00467 ssize_t BytesSended;
00468
00469 RioResult RioStatus;
00470
00471
00472 unsigned int NetDataSize;
00473
00474 char *Data;
00475
00476 #ifdef RIO_DEBUG1
00477 TCPCONNECTIONLOG << "[CTcpConnection - SendStreamData] Start" << endl;
00478 #endif
00479
00480 #ifdef RIO_DEBUG2
00481
00482 struct in_addr ip;
00483
00484
00485
00486 struct timeval Start, End;
00487 unsigned int DiffTime;
00488 #endif
00489
00490
00491 RioStatus = S_OK;
00492
00493
00494
00495 *DataSize = 0;
00496 *Param = NULL;
00497
00498 #ifdef RIO_DEBUG2
00499
00500 ip.s_addr = m_IP;
00501 #endif
00502
00503
00504 m_LastUseTime = time( NULL );
00505
00506 #ifdef RIO_DEBUG2
00507
00508 gettimeofday( &Start, NULL );
00509 #endif
00510
00511
00512 RioStatus = GetSendData( &Data, DataSize, Param );
00513 if( FAILED( RioStatus ) )
00514 {
00515 #ifdef RIO_DEBUG2
00516 TCPCONNECTIONLOG << "CTcpConnection::SendStreamData erro 0x" << hex
00517 << RioStatus << dec << " ("
00518 << GetErrorDescription( RioStatus ) << ") ao obter os "
00519 << "dados a serem enviados pela conexao TCP com o "
00520 << "socket com a ID " << m_Socket << "." << endl;
00521 #endif
00522
00523 #ifdef RIO_DEBUG1
00524 TCPCONNECTIONLOG << "[CTcpConnection - SendStreamData] Finish1" << endl;
00525 #endif
00526
00527 return RioStatus;
00528 }
00529
00530 #ifdef RIO_DEBUG2
00531
00532 gettimeofday( &End, NULL );
00533 DiffTime = ( End.tv_sec - Start.tv_sec ) * 1000 +
00534 ( End.tv_usec - Start.tv_usec ) / 1000;
00535 TCPCONNECTIONLOG << "CTcpConnection::SendStreamData tempo para executar a "
00536 << "funcao GetSendData para o socket com a ID " << m_Socket
00537 << ": " << DiffTime << " ms." << endl;
00538 #endif
00539
00540
00541
00542 if( *DataSize != 0 )
00543 {
00544
00545
00546
00547
00548
00549 NetDataSize = htonl( *DataSize );
00550
00551
00552
00553
00554
00555 #ifdef RIO_DEBUG2
00556
00557 gettimeofday( &Start, NULL );
00558 #endif
00559
00560 BytesSended = send( m_Socket, &NetDataSize, sizeof( unsigned int ),
00561 TCP_FLAGS_SENDSIZE );
00562
00563 #ifdef RIO_DEBUG2
00564
00565 gettimeofday( &End, NULL );
00566 DiffTime = ( End.tv_sec - Start.tv_sec ) * 1000 +
00567 ( End.tv_usec - Start.tv_usec ) / 1000;
00568 TCPCONNECTIONLOG << "CTcpConnection::SendStreamData tempo para "
00569 << "executar a funcao send (tamanho) para o socket "
00570 << "com a ID " << m_Socket << ": " << DiffTime
00571 << " ms." << endl;
00572 #endif
00573
00574
00575 if( BytesSended < 0 )
00576 {
00577 #ifdef RIO_DEBUG2
00578 TCPCONNECTIONLOG << "CTcpConnection::SendStreamData " << errno
00579 << " (" << strerror( errno ) << ") ao enviar "
00580 << "o tamanho " << *DataSize << " ao endereco IP "
00581 << inet_ntoa( ip ) << " e a porta "
00582 << ntohs( m_Port ) << " pelo socket com a ID "
00583 << m_Socket << "." << endl;
00584 #endif
00585
00586 RioStatus = ERROR_TCPCONNECTION + ERROR_SOCKET_SEND;
00587 }
00588 else if( BytesSended != sizeof( unsigned int ) )
00589 {
00590 #ifdef RIO_DEBUG2
00591 TCPCONNECTIONLOG << "CTcpConnection::SendStreamData nao foram "
00592 << "enviados bytes suficientes ao enviar o "
00593 << "tamanho dos dados para o endereco IP "
00594 << inet_ntoa( ip ) << " e a porta "
00595 << ntohs( m_Port ) << " pelo socket com a ID "
00596 << m_Socket << "." << endl;
00597 #endif
00598
00599 RioStatus = ERROR_TCPCONNECTION + ERROR_SOCKET_SEND;
00600 }
00601 else
00602 {
00603 #ifdef RIO_DEBUG2
00604
00605 gettimeofday( &Start, NULL );
00606 #endif
00607
00608
00609
00610
00611 BytesSended = send( m_Socket, Data, *DataSize, TCP_FLAGS_SENDDATA );
00612
00613 #ifdef RIO_DEBUG2
00614
00615 gettimeofday( &End, NULL );
00616 DiffTime = ( End.tv_sec - Start.tv_sec ) * 1000 +
00617 ( End.tv_usec - Start.tv_usec ) / 1000;
00618 TCPCONNECTIONLOG << "CTcpConnection::SendStreamData tempo para "
00619 << "executar a funcao send (dados) para o socket "
00620 << "com a ID : " << DiffTime << " ms." << endl;
00621 #endif
00622
00623
00624 if( BytesSended < 0 )
00625 {
00626 #ifdef RIO_DEBUG2
00627 TCPCONNECTIONLOG << "CTcpConnection::SendStreamData " << errno
00628 << " (" << strerror( errno ) << ") ao enviar "
00629 << "os dados ao endereco IP "
00630 << inet_ntoa( ip ) << " e a porta "
00631 << ntohs( m_Port ) << " pelo socket com a ID "
00632 << m_Socket << "." << endl;
00633 #endif
00634
00635 RioStatus = ERROR_TCPCONNECTION + ERROR_SOCKET_SEND;
00636 }
00637 else if( ( ( unsigned int ) BytesSended ) != *DataSize )
00638 {
00639 #ifdef RIO_DEBUG2
00640 TCPCONNECTIONLOG << "CTcpConnection::SendStreamData os dados "
00641 << "do endereco IP "<< inet_ntoa( ip )
00642 << " e a porta " << ntohs( m_Port ) << "pelo "
00643 << "socket com a ID " << m_Socket << " foram "
00644 << "enviados parcialmente, pois somente foram "
00645 << BytesSended << " bytes do total de "
00646 << *DataSize << "bytes." << endl;
00647 #endif
00648
00649 RioStatus = ERROR_TCPCONNECTION + ERROR_SOCKET_SEND;
00650 }
00651 #ifdef RIO_DEBUG2
00652 else
00653 {
00654 TCPCONNECTIONLOG << "CTcpConnection::SendStreamData foram "
00655 << "enviados " << *DataSize << " bytes com "
00656 << "sucesso pela conexao TCP com o socket com "
00657 << "a ID " << m_Socket << "." << endl;
00658
00659
00660 m_SendCount++;
00661 }
00662 #endif
00663 }
00664 }
00665 else
00666 {
00667
00668
00669 NetDataSize = htonl( 0 );
00670
00671 #ifdef RIO_DEBUG2
00672
00673 gettimeofday( &Start, NULL );
00674 #endif
00675
00676
00677 BytesSended = send( m_Socket, &NetDataSize, sizeof( unsigned int ),
00678 TCP_FLAGS_SENDDATA );
00679
00680 #ifdef RIO_DEBUG2
00681
00682 gettimeofday( &End, NULL );
00683 DiffTime = ( End.tv_sec - Start.tv_sec ) * 1000 +
00684 ( End.tv_usec - Start.tv_usec ) / 1000;
00685 TCPCONNECTIONLOG << "CTcpConnection::SendStreamData tempo para "
00686 << "executar a funcao send (tamanho 0) para o "
00687 << "socket com a ID " << m_Socket << ": " << DiffTime
00688 << " ms." << endl;
00689 #endif
00690
00691
00692 if( BytesSended < 0 )
00693 {
00694 #ifdef RIO_DEBUG2
00695 TCPCONNECTIONLOG << "CTcpConnection::SendStreamData " << errno
00696 << " (" << strerror( errno ) << ") ao enviar o "
00697 << "tamanho "<< *DataSize << " ao endereco IP "
00698 << inet_ntoa( ip ) << " e a porta "
00699 << ntohs( m_Port ) << " para o socket com a ID "
00700 << m_Socket << "." << endl;
00701 #endif
00702
00703 RioStatus = ERROR_TCPCONNECTION + ERROR_SOCKET_SEND;
00704 }
00705 else if( BytesSended != sizeof( unsigned int ) )
00706 {
00707 #ifdef RIO_DEBUG2
00708 TCPCONNECTIONLOG << "CTcpConnection::SendStreamData nao foram "
00709 << "enviados bytes suficientes ao enviar o "
00710 << "tamanho dos dados para o endereco IP "
00711 << inet_ntoa( ip ) << " e a porta "
00712 << ntohs( m_Port ) << " pelo socket com a ID "
00713 << m_Socket << "." << endl;
00714 #endif
00715
00716 RioStatus = ERROR_TCPCONNECTION + ERROR_SOCKET_SEND;
00717 }
00718 }
00719
00720 #ifdef RIO_DEBUG1
00721 TCPCONNECTIONLOG << "[CTcpConnection - SendStreamData] Finish2" << endl;
00722 #endif
00723
00724 return RioStatus;
00725 }
00726
00727
00728 bool CTcpConnection::WaitEnableConnection( void )
00729 {
00730
00731 bool isAborted;
00732
00733 #ifdef RIO_DEBUG1
00734 TCPCONNECTIONLOG << "[CTcpConnection - WaitEnableConnection] Start" << endl;
00735 #endif
00736
00737
00738 pthread_mutex_lock( &m_Mutex );
00739
00740
00741
00742 if( !m_SentSignal )
00743 pthread_cond_wait( &m_Cond, &m_Mutex );
00744
00745
00746 m_SentSignal = false;
00747
00748
00749
00750
00751
00752 isAborted = m_isAborted;
00753
00754
00755 pthread_mutex_unlock( &m_Mutex );
00756
00757 #ifdef RIO_DEBUG1
00758 TCPCONNECTIONLOG << "[CTcpConnection - WaitEnableConnection] Finish"
00759 << endl;
00760 #endif
00761
00762 return isAborted;
00763 }
00764
00765
00766
00767 bool CTcpConnection::TcpNetMgrThread( void )
00768 {
00769
00770
00771
00772
00773
00774 bool isConnectionActive;
00775
00776
00777 time_t CurrentTime;
00778
00779
00780 EClosedType ClosedType;
00781
00782 struct pollfd SoketsInfo[ TCPCONNECTIONSOCKETSNUMBER ];
00783
00784
00785 int PollTimeOut;
00786
00787
00788 RioResult RioStatus;
00789
00790 int SystemStatus;
00791
00792 in_addr ip;
00793
00794 #ifdef RIO_DEBUG2
00795
00796
00797 struct timeval Start, End;
00798
00799 struct timeval StartThread, EndThread;
00800
00801 unsigned int DiffTime;
00802 #endif
00803
00804 #ifdef RIO_DEBUG1
00805 TCPCONNECTIONLOG << "[CTcpConnection - TcpNetMgrThread] Start" << endl;
00806 #endif
00807
00808 #ifdef RIO_DEBUG2
00809
00810 if( m_ServerInstance )
00811 gettimeofday( &StartThread, NULL );
00812 #endif
00813
00814
00815 ip.s_addr = m_IP;
00816
00817 #ifdef RIO_DEBUG2
00818
00819
00820 if( m_ServerInstance )
00821 RioErr << "TCPNETMGRTHREADID START SYSID=" << syscall( SYS_gettid )
00822 << ", THREADID=" << pthread_self() << ", IP = "
00823 << inet_ntoa( ip ) << ", Port = " << ntohs( m_Port )
00824 << ", Socket = " << m_Socket << ", SYSTIME = " << time( NULL )
00825 << endl;
00826 #endif
00827
00828
00829
00830
00831
00832
00833 if( WaitEnableConnection() )
00834 {
00835 #ifdef RIO_DEBUG2
00836 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread a conexao para o "
00837 << "IP " << inet_ntoa( ip ) << ", a porta "
00838 << ntohs( m_Port ) << " e o socket com a ID "
00839 << m_Socket << " foi cancelada. Retornando da thread!"
00840 << endl;
00841 #endif
00842
00843 #ifdef RIO_DEBUG1
00844 TCPCONNECTIONLOG << "[CTcpConnection - TcpNetMgrThread] Finish1"
00845 << endl;
00846 #endif
00847
00848 return false;
00849 }
00850
00851
00852
00853 SoketsInfo[ TCPCONNECTIONSOCKETTCP ].fd = m_Socket;
00854 SoketsInfo[ TCPCONNECTIONSOCKETTCP ].events = POLLIN;
00855 SoketsInfo[ TCPCONNECTIONSOCKETUDP ].fd = m_PollSocket;
00856 SoketsInfo[ TCPCONNECTIONSOCKETUDP ].events = POLLIN;
00857
00858
00859 isConnectionActive = true;
00860
00861
00862
00863 ClosedType = CONNECTIONUNDEFINED;
00864
00865
00866 m_LastUseTime = time( NULL );
00867
00868
00869 while( isConnectionActive )
00870 {
00871
00872
00873
00874
00875
00876
00877 CurrentTime = time( NULL );
00878
00879
00880 pthread_mutex_lock( &m_Mutex );
00881
00882
00883
00884 if( ( m_ServerInstance ) && ( m_ConnectionTimeOut != 0 ) &&
00885 ( ( m_LastUseTime + m_ConnectionTimeOut ) < CurrentTime ) &&
00886 ( m_SendQueue.empty() ) )
00887 {
00888
00889
00890
00891 #ifdef RIO_DEBUG2
00892 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread a conexao "
00893 << "para o IP " << inet_ntoa( ip ) << " e a porta "
00894 << ntohs( m_Port ) << " sera fechada por timeout "
00895 << "porque " << m_LastUseTime + m_ConnectionTimeOut
00896 << " e menor do que " << CurrentTime << " , e nao "
00897 << "existem dados pendentes a serem enviados pelo "
00898 << "socket com a ID " << m_Socket << " porque o "
00899 << "tamanho da fila de envio e de "
00900 << m_SendQueue.size() << "." << endl;
00901 #endif
00902
00903
00904 isConnectionActive = false;
00905
00906
00907 ClosedType = CONNECTIONTIMEOUT;
00908 }
00909
00910
00911
00912 if( m_SendQueue.empty() )
00913 SoketsInfo[ TCPCONNECTIONSOCKETTCP ].events &= POLLIN;
00914 else
00915 SoketsInfo[ TCPCONNECTIONSOCKETTCP ].events |= POLLOUT;
00916
00917
00918 pthread_mutex_unlock( &m_Mutex );
00919
00920
00921
00922 if( isConnectionActive )
00923 {
00924
00925
00926
00927
00928
00929 if( m_ServerInstance )
00930 {
00931
00932
00933 PollTimeOut = m_LastUseTime + m_ConnectionTimeOut -
00934 time( NULL );
00935 if( PollTimeOut < 0 )
00936 PollTimeOut = 0;
00937 else
00938 PollTimeOut = PollTimeOut * 1000;
00939 }
00940 else
00941
00942
00943
00944 PollTimeOut = -1;
00945
00946 #ifdef RIO_DEBUG2
00947 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread antes de "
00948 << "executar o poll, Flags do socket TCP com a ID "
00949 << m_Socket << ": [";
00950 if( ( SoketsInfo[ TCPCONNECTIONSOCKETTCP ].events & POLLIN ) != 0 )
00951 TCPCONNECTIONLOG << "POLLIN ";
00952 if( ( SoketsInfo[ TCPCONNECTIONSOCKETTCP ].events & POLLOUT ) != 0 )
00953 TCPCONNECTIONLOG << "POLLOUT ";
00954 TCPCONNECTIONLOG << "], Flags do socket UDP com a ID "
00955 << m_PollSocket << ": [";
00956 if( ( SoketsInfo[ TCPCONNECTIONSOCKETUDP ].events & POLLIN ) != 0 )
00957 TCPCONNECTIONLOG << "POLLIN ";
00958 if( ( SoketsInfo[ TCPCONNECTIONSOCKETUDP ].events & POLLOUT ) != 0 )
00959 TCPCONNECTIONLOG << "POLLOUT ";
00960 TCPCONNECTIONLOG << "], Timeout = " << PollTimeOut << "." << endl;
00961 #endif
00962
00963
00964
00965
00966 SystemStatus = poll( SoketsInfo, TCPCONNECTIONSOCKETSNUMBER,
00967 PollTimeOut );
00968
00969 #ifdef RIO_DEBUG2
00970 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread depois de "
00971 << "executar o poll, erro = " << errno << " ("
00972 << strerror( errno ) << ")." << endl;
00973 #endif
00974
00975 if( SystemStatus < 0 )
00976 {
00977 if( errno == EINTR )
00978 {
00979 #ifdef RIO_DEBUG2
00980 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread "
00981 << "recebi o erro que a chamada ao "
00982 << "sistema foi interrompida." << endl;
00983 #endif
00984 }
00985 else
00986 {
00987 #ifdef RIO_DEBUG2
00988 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread erro "
00989 << errno << " (" << strerror( errno )
00990 << ") ao executar o comando poll para o "
00991 << "socket com a ID " << m_Socket << "."
00992 << endl;
00993 #endif
00994
00995
00996
00997 m_NetTcp->ProcessError( m_IP, m_Port, ERROR_NETTCP +
00998 ERROR_SOCKETS_SELECT,
00999 "TcpNetMgrThread-poll",
01000 OTHERERROR,
01001 ( void * ) NULLTRANSFERID );
01002 }
01003 }
01004 else
01005 {
01006 #ifdef RIO_DEBUG2
01007 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread a funcao "
01008 << "poll executada com sucesso!" << endl;
01009 #endif
01010 }
01011
01012
01013 if( ( SoketsInfo[ TCPCONNECTIONSOCKETUDP ].revents & POLLIN ) != 0 )
01014 {
01015
01016
01017 char Message[ MSG_POLL_SIZE + 1 ];
01018
01019
01020 memset( Message, 0, MSG_POLL_SIZE + 1 );
01021
01022
01023
01024 if( recv( m_PollSocket, Message, MSG_POLL_SIZE,
01025 UDP_FLAGS_RECEIVE ) < 0 )
01026 {
01027 #ifdef RIO_DEBUG2
01028 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread erro "
01029 << errno << " (" << strerror( errno )
01030 << ") ao tentar receber a mensagem usada "
01031 << "para desbloquear o poll." << endl;
01032 #endif
01033 }
01034 #ifdef RIO_DEBUG2
01035 else
01036 {
01037 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread dados "
01038 << "detectados no socket usado para "
01039 << "desbloquear o poll. A mensagem "
01040 << "passada foi \"" << Message << "\"."
01041 << endl;
01042 }
01043 #endif
01044 }
01045
01046
01047
01048
01049 if( ( SoketsInfo[ TCPCONNECTIONSOCKETTCP ].revents & POLLIN ) != 0 )
01050 {
01051
01052
01053 char *ReceivedData;
01054
01055
01056 unsigned int ReceivedDataSize;
01057
01058 #ifdef RIO_DEBUG2
01059
01060 gettimeofday( &Start, NULL );
01061 #endif
01062
01063
01064 RioStatus = ReceiveStreamData( &ReceivedData,
01065 &ReceivedDataSize );
01066
01067 #ifdef RIO_DEBUG2
01068
01069 gettimeofday( &End, NULL );
01070 DiffTime = ( End.tv_sec - Start.tv_sec ) * 1000 +
01071 ( End.tv_usec - Start.tv_usec ) / 1000;
01072 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread tempo "
01073 << "para executar a funcao ReceiveStreamData "
01074 << "para o socket com a ID " << m_Socket
01075 << ": " << DiffTime << " ms." << endl;
01076 #endif
01077
01078
01079 if( FAILED( RioStatus ) )
01080 {
01081
01082
01083
01084 #ifdef RIO_DEBUG2
01085 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread erro "
01086 << " 0x" << hex << RioStatus << dec << " ("
01087 << GetErrorDescription( RioStatus ) << ") "
01088 << "ao receber dados pela conexao TCP "
01089 << "associada ao IP " << inet_ntoa( ip )
01090 << ", a porta " << ntohs( m_Port )
01091 << "pelo socket com o ID " << m_Socket
01092 << endl;
01093 #endif
01094
01095
01096
01097 m_NetTcp->ProcessError( m_IP, m_Port, RioStatus,
01098 "TcpNetMgrThread-ReceiveStreamData",
01099 RECEIVEERROR,
01100 ( void * ) NULLTRANSFERID );
01101 }
01102 else
01103 {
01104
01105
01106 if( ReceivedDataSize == 0 )
01107 {
01108
01109 pthread_mutex_lock( &m_Mutex );
01110
01111
01112
01113 #ifdef RIO_DEBUG2
01114 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread "
01115 << "conexao TCP com o IP "
01116 << inet_ntoa( ip ) << ", a porta "
01117 << ntohs( m_Port ) << " e com o "
01118 << "socket com a ID " << m_Socket
01119 << " foi fechada pelo outro lado."
01120 << endl;
01121 #endif
01122
01123
01124 SoketsInfo[ TCPCONNECTIONSOCKETTCP ].revents &= POLLIN;
01125
01126
01127
01128 isConnectionActive = false;
01129
01130
01131
01132 ClosedType = CONNECTIONCLOSEDREMOTELLY;
01133
01134
01135 pthread_mutex_unlock( &m_Mutex );
01136 }
01137 else
01138 {
01139
01140
01141
01142 #ifdef RIO_DEBUG2
01143 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread "
01144 << "Recebidos " << ReceivedDataSize
01145 << " bytes pelo IP " << inet_ntoa( ip )
01146 << " e da porta " << ntohs( m_Port )
01147 << "pelo socket com a ID "
01148 << m_Socket << "." << endl;
01149 #endif
01150
01151 #ifdef RIO_DEBUG2
01152
01153 gettimeofday( &Start, NULL );
01154 #endif
01155
01156
01157
01158 m_NetTcp->ProcessData( m_IP, m_Port, ReceivedData,
01159 ReceivedDataSize );
01160
01161 #ifdef RIO_DEBUG2
01162
01163 gettimeofday( &End, NULL );
01164 DiffTime = ( End.tv_sec - Start.tv_sec ) * 1000 +
01165 ( End.tv_usec - Start.tv_usec ) / 1000;
01166 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread "
01167 << "tempo para executar a funcao "
01168 << "ProcessData para o socket com a "
01169 << "ID " << m_Socket << ": "
01170 << DiffTime << " ms." << endl;
01171 #endif
01172
01173
01174
01175
01176 delete[] ReceivedData;
01177 }
01178 }
01179 }
01180
01181
01182
01183
01184 if( ( SoketsInfo[ TCPCONNECTIONSOCKETTCP ].revents & POLLOUT )
01185 != 0 )
01186 {
01187
01188 unsigned int DataSize;
01189 void *Param;
01190
01191 #ifdef RIO_DEBUG2
01192
01193 gettimeofday( &Start, NULL );
01194 #endif
01195
01196
01197 RioStatus = SendStreamData( &DataSize, &Param );
01198
01199 #ifdef RIO_DEBUG2
01200
01201 gettimeofday( &End, NULL );
01202 DiffTime = ( End.tv_sec - Start.tv_sec ) * 1000 +
01203 ( End.tv_usec - Start.tv_usec ) / 1000;
01204 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread tempo "
01205 << "para executar a funcao SendStreamData "
01206 << "para o socket com a ID " << m_Socket
01207 << ": " << DiffTime << " ms." << endl;
01208 #endif
01209
01210
01211 if( FAILED( RioStatus ) )
01212 {
01213
01214
01215 #ifdef RIO_DEBUG2
01216 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread erro "
01217 << "0x" << hex << RioStatus << dec << " ("
01218 << GetErrorDescription( RioStatus )
01219 << ") ao enviar dados pela conexao TCP "
01220 << "associada ao IP " << inet_ntoa( ip )
01221 << ", a porta " << ntohs( m_Port ) << " e "
01222 << "o socket com a ID " << m_Socket << "."
01223 << endl;
01224 #endif
01225
01226
01227
01228 m_NetTcp->ProcessError( m_IP, m_Port, RioStatus,
01229 "TcpNetMgrThread-SendStreamData",
01230 SENDERROR, Param );
01231 }
01232 else
01233 {
01234
01235
01236
01237 if( DataSize == 0 )
01238 {
01239
01240 pthread_mutex_lock( &m_Mutex );
01241
01242 #ifdef RIO_DEBUG2
01243 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread "
01244 << "conexao TCP com o IP "
01245 << inet_ntoa( ip ) << ", a porta "
01246 << ntohs( m_Port ) << " e com o "
01247 << "socket com a ID " << m_Socket
01248 << " foi fechada pelo por este lado. "
01249 << endl;
01250 #endif
01251
01252
01253
01254 isConnectionActive = false;
01255
01256
01257
01258 ClosedType = CONNECTIONCLOSEDLOCALLY;
01259
01260
01261 pthread_mutex_unlock( &m_Mutex );
01262 }
01263 else
01264 {
01265 #ifdef RIO_DEBUG2
01266 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread os "
01267 << DataSize << " bytes dos dados "
01268 << "foram enviados com sucesso pela "
01269 << "conexao TCP com o IP "
01270 << inet_ntoa( ip ) << ", a porta "
01271 << ntohs( m_Port )
01272 << " e com socket a ID " << m_Socket
01273 << "." << endl;
01274 #endif
01275
01276
01277
01278
01279 if( ( m_ServerInstance ) && ( m_LogRotation != NULL ) )
01280 {
01281
01282
01283
01284 char StrPacketSize[ 11 ];
01285 sprintf( StrPacketSize, "%d", DataSize );
01286 RioStatus = m_LogRotation->NewLogLine( time( NULL ),
01287 StrPacketSize
01288 );
01289 #ifdef RIO_DEBUG2
01290 if( FAILED( RioStatus ) )
01291 TCPCONNECTIONLOG << "CTcpConnection::"
01292 << "TcpNetMgrThread erro 0x"
01293 << hex << RioStatus << dec
01294 << " ("
01295 << GetErrorDescription(
01296 RioStatus )
01297 << ") ao escrever no log."
01298 << endl;
01299 #endif
01300 }
01301
01302 #ifdef RIO_DEBUG2
01303
01304 gettimeofday( &Start, NULL );
01305 #endif
01306
01307
01308
01309 m_NetTcp->SendDataCompleted( m_IP, m_Port, Param );
01310
01311 #ifdef RIO_DEBUG2
01312
01313 gettimeofday( &End, NULL );
01314 DiffTime = ( End.tv_sec - Start.tv_sec ) * 1000 +
01315 ( End.tv_usec - Start.tv_usec ) / 1000;
01316 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread "
01317 << "tempo para executar a funcao "
01318 << "SendDataCompleted para o socket "
01319 << "com a ID " << m_Socket << ": "
01320 << DiffTime << " ms." << endl;
01321 #endif
01322 }
01323 }
01324 }
01325
01326 #ifdef RIO_DEBUG2
01327
01328
01329 if( ( SoketsInfo[ TCPCONNECTIONSOCKETTCP ].revents & POLLPRI )
01330 != 0 )
01331 {
01332 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread evento "
01333 << "POLLPRI detectado no socket TCP com a "
01334 << "ID " << m_Socket << "." << endl;
01335 }
01336 if( ( SoketsInfo[ TCPCONNECTIONSOCKETUDP ].revents & POLLPRI )
01337 != 0 )
01338 {
01339 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread evento "
01340 << "POLLPRI detectado no socket UDP com a "
01341 << "ID " << m_PollSocket << "." << endl;
01342 }
01343 if( ( SoketsInfo[ TCPCONNECTIONSOCKETTCP ].revents & POLLERR )
01344 != 0 )
01345 {
01346 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread evento "
01347 << "POLLERR detectado no socket TCP com a "
01348 << "ID " << m_Socket << "." << endl;
01349 }
01350 if( ( SoketsInfo[ TCPCONNECTIONSOCKETUDP ].revents & POLLERR )
01351 != 0 )
01352 {
01353 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread evento "
01354 << "POLLERR detectado no socket UDP com a "
01355 << "ID " << m_PollSocket << "." << endl;
01356 }
01357 if( ( SoketsInfo[ TCPCONNECTIONSOCKETTCP ].revents & POLLHUP )
01358 != 0 )
01359 {
01360 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread evento "
01361 << "POLLHUP detectado no socket TCP com a "
01362 << "ID " << m_Socket << "." << endl;
01363 }
01364 if( ( SoketsInfo[ TCPCONNECTIONSOCKETUDP ].revents & POLLHUP )
01365 != 0 )
01366 {
01367 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread evento "
01368 << "POLLHUP detectado no socket UDP com a "
01369 << "ID " << m_PollSocket << "." << endl;
01370 }
01371 if( ( SoketsInfo[ TCPCONNECTIONSOCKETTCP ].revents & POLLNVAL )
01372 != 0 )
01373 {
01374 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread evento "
01375 << "POLLNVAL detectado no socket TCP com a "
01376 << "ID " << m_Socket << "." << endl;
01377 }
01378 if( ( SoketsInfo[ TCPCONNECTIONSOCKETUDP ].revents & POLLNVAL )
01379 != 0 )
01380 {
01381 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread evento "
01382 << "POLLNVAL detectado no socket UDP com a "
01383 << "ID " << m_PollSocket << "." << endl;
01384 }
01385 #endif
01386
01387 }
01388 }
01389
01390
01391
01392 #ifdef RIO_DEBUG2
01393
01394 gettimeofday( &Start, NULL );
01395 #endif
01396
01397
01398
01399 m_NetTcp->ConnectionClosed( m_IP, m_Port, ClosedType );
01400
01401 #ifdef RIO_DEBUG2
01402
01403 gettimeofday( &End, NULL );
01404 DiffTime = ( End.tv_sec - Start.tv_sec ) * 1000 +
01405 ( End.tv_usec - Start.tv_usec ) / 1000;
01406 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread tempo para executar a "
01407 << "funcao ConnectionClosed para o socket com a ID "
01408 << m_Socket << ": " << DiffTime << " ms." << endl;
01409 #endif
01410
01411
01412 pthread_mutex_lock( &m_Mutex );
01413
01414
01415
01416
01417 if( m_SendQueue.size() > 0 )
01418 {
01419 #ifdef RIO_DEBUG2
01420 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread Existia(m) um "
01421 << "conjunto(s) de " << m_SendQueue.size() << " dados "
01422 << "pendentes para serem enviados! Os dados serao ignorados!"
01423 << endl;
01424 #endif
01425 }
01426
01427
01428 pthread_mutex_unlock( &m_Mutex );
01429
01430
01431 shutdown( m_Socket, SHUT_RDWR );
01432
01433
01434 close( m_Socket );
01435
01436
01437 shutdown( m_PollSocket, SHUT_RDWR );
01438
01439
01440 close( m_PollSocket );
01441
01442
01443
01444 #ifdef RIO_DEBUG2
01445 TCPCONNECTIONLOG << "CTcpConnection::TcpNetMgrThread conexao TCP com o IP "
01446 << inet_ntoa( ip ) << ", a porta " << ntohs( m_Port )
01447 << " e com o socket com a ID " << m_Socket << " foi "
01448 << "fechada ";
01449 switch( ClosedType )
01450 {
01451 case CONNECTIONCLOSEDLOCALLY:
01452 TCPCONNECTIONLOG << "localmente.";
01453 break;
01454 case CONNECTIONCLOSEDREMOTELLY:
01455 TCPCONNECTIONLOG << "remotamente.";
01456 break;
01457 case CONNECTIONTIMEOUT:
01458 TCPCONNECTIONLOG << "devido a um timeout (depois de "
01459 << m_ConnectionTimeOut << " segundos).";
01460 break;
01461 default:
01462 TCPCONNECTIONLOG << "(valor " << ClosedType << "e o "
01463 << "CONNECTIONUNDEFINED ou invalido, e nao "
01464 << "deveria ter sido usado!).";
01465 break;
01466 }
01467 TCPCONNECTIONLOG << "Dados enviados = " << m_SendCount << " e dados "
01468 << "recebidos = " << m_ReceiveCount << "." << endl;
01469 #endif
01470
01471 #ifdef RIO_DEBUG2
01472 if( m_ServerInstance )
01473 {
01474
01475 gettimeofday( &EndThread, NULL );
01476
01477
01478 DiffTime = ( EndThread.tv_sec - StartThread.tv_sec ) * 1000 +
01479 ( EndThread.tv_usec - StartThread.tv_usec ) / 1000;
01480
01481 RioErr << "TCPNETMGRTHREADID END, SYSID=" << syscall( SYS_gettid )
01482 << ", THREADID=" << pthread_self() << ", IP = "
01483 << inet_ntoa( ip ) << ", Port = " << ntohs( m_Port )
01484 << ", Socket = " << m_Socket << ", Time = " << DiffTime << "ms."
01485 << endl;
01486 }
01487 #endif
01488
01489 #ifdef RIO_DEBUG1
01490 TCPCONNECTIONLOG << "[CTcpConnection - TcpNetMgrThread] Finish2" << endl;
01491 #endif
01492
01493 return true;
01494 }
01495
01496
01497
01498
01499 void *CTcpConnection::TcpNetMgrThreadEp( void *ThreadParam )
01500 {
01501
01502 CTcpConnection *TcpConnection = ( CTcpConnection * ) ThreadParam;
01503
01504 bool ThreadResult;
01505
01506 #ifdef RIO_DEBUG1
01507 TCPCONNECTIONLOGEST << "[CTcpConnection - TcpNetMgrThreadEp] Start" << endl;
01508 #endif
01509
01510
01511 ThreadResult = TcpConnection->TcpNetMgrThread();
01512
01513
01514
01515
01516
01517 if( ThreadResult )
01518 delete TcpConnection;
01519
01520 #ifdef RIO_DEBUG1
01521 TCPCONNECTIONLOGEST << "[CTcpConnection - TcpNetMgrThreadEp] Finish"
01522 << endl;
01523 #endif
01524
01525 return NULL;
01526 }
01527
01528
01529 RioResult CTcpConnection::Initialize( int IP, int Port, int Socket, int HostIP,
01530 time_t ConnectionTimeOut,
01531 CLogRotation *LogRotation )
01532 {
01533
01534 pthread_attr_t attribTcpNetMgrThread;
01535
01536
01537 struct sockaddr_in TempAddr;
01538
01539 socklen_t AddrSize;
01540
01541 #ifdef RIO_DEBUG1
01542 TCPCONNECTIONLOG << "[CTcpConnection - Initialize] Start" << endl;
01543 #endif
01544
01545
01546 if( m_Initialized )
01547 {
01548 #ifdef RIO_DEBUG2
01549 TCPCONNECTIONLOG << "CTcpConnection::Initialize o objeto da classe ja "
01550 << "esta inicializado!" << endl;
01551 #endif
01552
01553 #ifdef RIO_DEBUG1
01554 TCPCONNECTIONLOG << "[CTcpConnection - Initialize] Finish1" << endl;
01555 #endif
01556
01557 return ERROR_TCPCONNECTION + ERROR_INITIALIZED;
01558 }
01559
01560
01561 m_IP = IP;
01562 m_Port = Port;
01563 m_Socket = Socket;
01564 m_ConnectionTimeOut = ConnectionTimeOut;
01565 m_LogRotation = LogRotation;
01566 m_SentSignal = false;
01567 #ifdef RIO_DEBUG2
01568 m_ReceiveCount = 0;
01569 m_SendCount = 0;
01570 #endif
01571
01572
01573
01574
01575 m_PollSocket = socket( AF_INET, SOCK_DGRAM, 0 );
01576 if( m_PollSocket < 0 )
01577 {
01578 #ifdef RIO_DEBUG2
01579 TCPCONNECTIONLOG << "CTcpConnection::Initialize erro " << errno << " ("
01580 << strerror( errno ) << ") ao criar o socket usado "
01581 << "para desbloquear o poll quando necessario."
01582 << endl;
01583 #endif
01584
01585 #ifdef RIO_DEBUG1
01586 TCPCONNECTIONLOG << "[CTcpConnection - Initialize] Finish2" << endl;
01587 #endif
01588
01589 return ERROR_NETTCP + ERROR_SOCKET_CREATE;
01590 }
01591
01592
01593
01594 if( fcntl( m_PollSocket, F_SETFD, FD_CLOEXEC ) < 0 )
01595 {
01596 #ifdef RIO_DEBUG2
01597 TCPCONNECTIONLOG << "CTcpConnection::Initialize erro " << errno << " ("
01598 << strerror( errno ) << ") ao fazer o socket usado "
01599 << "para desbloquear o poll ser exclusivo ao processo "
01600 << "que criou o objeto da classe CTcpConnection."
01601 << endl;
01602 #endif
01603
01604 #ifdef RIO_DEBUG1
01605 TCPCONNECTIONLOG << "[CTcpConnection - Initialize] Finish3" << endl;
01606 #endif
01607
01608 return ERROR_NETTCP + ERROR_SOCKET_OPTIONS;
01609 }
01610
01611
01612 memset( &TempAddr, 0, sizeof( TempAddr ) );
01613
01614
01615
01616 TempAddr.sin_family = AF_INET;
01617 TempAddr.sin_addr.s_addr = HostIP;
01618 TempAddr.sin_port = 0;
01619 if( bind( m_PollSocket, ( struct sockaddr * ) &TempAddr,
01620 sizeof( TempAddr ) ) < 0 )
01621 {
01622 #ifdef RIO_DEBUG2
01623 TCPCONNECTIONLOG << "CTcpConnection::Initialize erro " << errno << " ("
01624 << strerror( errno ) << ") ao ligar o socket usado "
01625 << "para desbloquear o poll ao IP "
01626 << inet_ntoa( TempAddr.sin_addr ) << "." << endl;
01627 #endif
01628
01629 #ifdef RIO_DEBUG1
01630 TCPCONNECTIONLOG << "[CTcpConnection - Initialize] Finish4" << endl;
01631 #endif
01632
01633 return ERROR_NETTCP + ERROR_SOCKET_BIND;
01634 }
01635
01636 AddrSize = sizeof( m_PollSocketAddr );
01637 if( getsockname( m_PollSocket, ( struct sockaddr * ) &m_PollSocketAddr,
01638 &AddrSize ) != 0 )
01639 {
01640 #ifdef RIO_DEBUG2
01641 TCPCONNECTIONLOG << "CTcpConnection::Initialize erro " << errno << " ("
01642 << strerror( errno ) << ") ao obter as informacoes do "
01643 << "socket usado para desbloquear o poll ao IP "
01644 << inet_ntoa( TempAddr.sin_addr ) << "." << endl;
01645 #endif
01646
01647 #ifdef RIO_DEBUG1
01648 TCPCONNECTIONLOG << "[CTcpConnection - Initialize] Finish5" << endl;
01649 #endif
01650
01651 return ERROR_NETTCP + ERROR_SOCKET_OPTIONS;
01652 }
01653
01654 #ifdef RIO_DEBUG2
01655 TCPCONNECTIONLOG << "CTcpConnection::Initialize socket usado para "
01656 << "desbloquear o poll criado sucesso. O identificador do "
01657 << "socket e " << m_PollSocket << ", e foi associado ao "
01658 << "endereco IP " << inet_ntoa( m_PollSocketAddr.sin_addr )
01659 << " e a porta " << ntohs( m_PollSocketAddr.sin_port )
01660 << "." << endl;
01661 #endif
01662
01663
01664
01665 pthread_attr_init( &attribTcpNetMgrThread );
01666
01667
01668 pthread_attr_setstacksize( &attribTcpNetMgrThread, 2 * PTHREAD_STACK_MIN );
01669
01670
01671 if ( pthread_create( &m_TcpNetMgrThreadId, &attribTcpNetMgrThread,
01672 TcpNetMgrThreadEp, ( void * ) this ) != 0 )
01673 {
01674 #ifdef RIO_DEBUG2
01675 TCPCONNECTIONLOG << "CTcpConnection::Initialize erro " << errno
01676 << " (" << strerror( errno ) << ") ao criar a thread "
01677 << "TcpNetMgrThread." << endl;
01678 #endif
01679
01680 #ifdef RIO_DEBUG1
01681 TCPCONNECTIONLOG << "[CTcpConnection - Initialize] Finish6" << endl;
01682 #endif
01683
01684 return ERROR_TCPCONNECTION + ERROR_CREATE_THREAD;
01685 }
01686
01687
01688
01689 pthread_detach( m_TcpNetMgrThreadId );
01690
01691
01692 m_Initialized = true;
01693
01694 #ifdef RIO_DEBUG1
01695 TCPCONNECTIONLOG << "[CTcpConnection - Initialize] Finish7" << endl;
01696 #endif
01697
01698 return S_OK;
01699 }
01700
01701
01702
01703
01704 RioResult CTcpConnection::EnableConnection( void )
01705 {
01706 #ifdef RIO_DEBUG1
01707 TCPCONNECTIONLOG << "[CTcpConnection - EnableConnection] Start" << endl;
01708 #endif
01709
01710
01711 if( !m_Initialized )
01712 {
01713 #ifdef RIO_DEBUG2
01714 TCPCONNECTIONLOG << "CTcpConnection::EnableConnection o objeto da "
01715 << "classe nao esta inicializado!" << endl;
01716 #endif
01717
01718 #ifdef RIO_DEBUG1
01719 TCPCONNECTIONLOG << "[CTcpConnection - EnableConnection] Finish1"
01720 << endl;
01721 #endif
01722
01723 return ERROR_TCPCONNECTION + ERROR_NOT_INITIALIZED;
01724 }
01725
01726
01727 pthread_mutex_lock( &m_Mutex );
01728
01729
01730
01731 pthread_cond_signal( &m_Cond );
01732
01733
01734 m_SentSignal = true;
01735
01736
01737 pthread_mutex_unlock( &m_Mutex );
01738
01739 #ifdef RIO_DEBUG1
01740 TCPCONNECTIONLOG << "[CTcpConnection - EnableConnection] Finish2" << endl;
01741 #endif
01742
01743 return S_OK;
01744 }
01745
01746
01747
01748 RioResult CTcpConnection::CancelConnection( void )
01749 {
01750 #ifdef RIO_DEBUG1
01751 TCPCONNECTIONLOG << "[CTcpConnection - CancelConnection] Start" << endl;
01752 #endif
01753
01754
01755 if( !m_Initialized )
01756 {
01757 #ifdef RIO_DEBUG2
01758 TCPCONNECTIONLOG << "CTcpConnection::CancelConnection o objeto da "
01759 << "classe nao esta inicializado!" << endl;
01760 #endif
01761
01762 #ifdef RIO_DEBUG1
01763 TCPCONNECTIONLOG << "[CTcpConnection - CancelConnection] Finish1"
01764 << endl;
01765 #endif
01766
01767 return ERROR_TCPCONNECTION + ERROR_NOT_INITIALIZED;
01768 }
01769
01770
01771 pthread_mutex_lock( &m_Mutex );
01772
01773
01774
01775 m_isAborted = true;
01776
01777
01778
01779 pthread_cond_signal( &m_Cond );
01780
01781
01782 m_SentSignal = true;
01783
01784
01785 pthread_mutex_unlock( &m_Mutex );
01786
01787
01788 pthread_join( m_TcpNetMgrThreadId, NULL );
01789
01790 #ifdef RIO_DEBUG1
01791 TCPCONNECTIONLOG << "[CTcpConnection - EnableConnection] Finish2" << endl;
01792 #endif
01793
01794 return S_OK;
01795 }
01796
01797
01798
01799 RioResult CTcpConnection::PutSendData( char *Data, unsigned int DataSize,
01800 void *Param,
01801 unsigned int *SendDataSize )
01802 {
01803
01804 SSendData SendData;
01805
01806 #ifdef RIO_DEBUG2
01807
01808 in_addr ip;
01809 #endif
01810
01811 #ifdef RIO_DEBUG1
01812 TCPCONNECTIONLOG << "[CTcpConnection - PutSendData] Start" << endl;
01813 #endif
01814
01815 #ifdef RIO_DEBUG2
01816
01817 ip.s_addr = m_IP;
01818 #endif
01819
01820
01821 if( !m_Initialized )
01822 {
01823 #ifdef RIO_DEBUG2
01824 TCPCONNECTIONLOG << "CTcpConnection::PutSendData o objeto da classe "
01825 << "nao esta inicializado!" << endl;
01826 #endif
01827
01828 #ifdef RIO_DEBUG1
01829 TCPCONNECTIONLOG << "[CTcpConnection - PutSendData] Finish1"
01830 << endl;
01831 #endif
01832
01833 return ERROR_TCPCONNECTION + ERROR_NOT_INITIALIZED;
01834 }
01835
01836
01837 pthread_mutex_lock( &m_Mutex );
01838
01839
01840
01841 if( m_isClosingSocket )
01842 {
01843
01844 pthread_mutex_unlock( &m_Mutex );
01845
01846 #ifdef RIO_DEBUG2
01847 TCPCONNECTIONLOG << "CTcpConnection::PutSendData o socket com a ID "
01848 << m_Socket << " esta sendo fechado. Nao e possivel "
01849 << "portanto colocar mais dados na fila de saida."
01850 << endl;
01851 #endif
01852
01853 #ifdef RIO_DEBUG1
01854 TCPCONNECTIONLOG << "[CTcpConnection - PutSendData] Finish2" << endl;
01855 #endif
01856
01857 return ERROR_TCPCONNECTION + ERROR_NOTCONNECTED;
01858 }
01859
01860
01861 SendData.Data = Data;
01862 SendData.DataSize = DataSize;
01863 SendData.Param = Param;
01864
01865
01866 try
01867 {
01868 #ifdef RIO_DEBUG2
01869 TCPCONNECTIONLOG << "CTcpConnection::PutSendData tentando colocar os "
01870 << "dados a serem enviados pelo socket com a ID "
01871 << m_Socket << ". Tamanho da fila e de "
01872 << m_SendQueue.size() << "." << endl;
01873 #endif
01874
01875 m_SendQueue.push( SendData );
01876
01877 #ifdef RIO_DEBUG2
01878 TCPCONNECTIONLOG << "CTcpConnection::PutSendData os dados a serem "
01879 << "enviados pelo socket com a ID " << m_Socket
01880 << ", o IP " << inet_ntoa( ip ) << " e a porta "
01881 << ntohs( m_Port ) << " foram colocados na fila com "
01882 << "sucesso. Tamanho da fila agora e de "
01883 << m_SendQueue.size() << "." << endl;
01884 #endif
01885 }
01886 catch( bad_alloc& ba )
01887 {
01888
01889 *SendDataSize = m_SendQueue.size();
01890
01891
01892 pthread_mutex_unlock( &m_Mutex );
01893
01894 #ifdef RIO_DEBUG2
01895 TCPCONNECTIONLOG << "CTcpConnection::PutSendData erro de alocacao de "
01896 << "memoria (bad_alloc, error = " << ba.what() << ") "
01897 << "ao criar uma entrada na fila SendQueue do socket "
01898 << "com a ID " << m_Socket << ", o IP "
01899 << inet_ntoa( ip ) << " e a porta " << ntohs( m_Port )
01900 << "." << endl;
01901 #endif
01902
01903 #ifdef RIO_DEBUG1
01904 TCPCONNECTIONLOG << "[CTcpConnection - PutSendData] Finish3" << endl;
01905 #endif
01906
01907 return ERROR_TCPCONNECTION + ERROR_MEMORY;
01908
01909 }
01910
01911
01912 *SendDataSize = m_SendQueue.size();
01913
01914
01915
01916
01917
01918
01919 if( ( *SendDataSize ) == 1 )
01920 {
01921 #ifdef RIO_DEBUG2
01922 TCPCONNECTIONLOG << "CTcpConnection::PutSendData tentanto desbloquear "
01923 << "o poll, enviando a mensagem \"" << MSG_POLL_NEWDATA
01924 << "\" ao socket com a ID " << m_PollSocket << "."
01925 << endl;
01926 #endif
01927 if( sendto( m_PollSocket, ( void * ) MSG_POLL_NEWDATA,
01928 MSG_POLL_SIZE, UDP_FLAGS_SEND,
01929 ( struct sockaddr * ) &m_PollSocketAddr,
01930 sizeof( m_PollSocketAddr ) ) < 0 )
01931 {
01932 #ifdef RIO_DEBUG2
01933 TCPCONNECTIONLOG << "CTcpConnection::PutSendData erro " << errno
01934 << " (" << strerror( errno ) << ") ao enviar "
01935 << "dados pelo socket usado para desbloquear o "
01936 << "poll com a ID " << m_PollSocket
01937 << ". Esperando entao pelo proximo dado a ser "
01938 << "enviado!" << endl;
01939 #endif
01940 }
01941 }
01942
01943
01944 pthread_mutex_unlock( &m_Mutex );
01945
01946 #ifdef RIO_DEBUG1
01947 TCPCONNECTIONLOG << "[CTcpConnection - PutSendData] Finish4" << endl;
01948 #endif
01949
01950 return S_OK;
01951 }
01952
01953
01954
01955 RioResult CTcpConnection::GetIpAndPort( int *IP, int *Port )
01956 {
01957
01958 if( !m_Initialized )
01959 {
01960
01961 *IP = 0;
01962 *Port = 0;
01963
01964 #ifdef RIO_DEBUG2
01965 TCPCONNECTIONLOG << "CTcpConnection::GetIpAndPort o objeto da classe "
01966 << "nao esta inicializado!" << endl;
01967 #endif
01968
01969 #ifdef RIO_DEBUG1
01970 TCPCONNECTIONLOG << "[CTcpConnection - GetIpAndPort] Finish1" << endl;
01971 #endif
01972
01973 return ERROR_TCPCONNECTION + ERROR_NOT_INITIALIZED;
01974 }
01975
01976 *IP = m_IP;
01977 *Port = m_Port;
01978
01979 #ifdef RIO_DEBUG1
01980 TCPCONNECTIONLOG << "[CTcpConnection - GetIpAndPort] Finish2" << endl;
01981 #endif
01982
01983 return S_OK;
01984 }
01985
01986
01987
01988
01989
01990
01991
01992 CNetTcp::CNetTcp( CNetInterface *NetInterface )
01993 {
01994
01995 m_NetInterface = NetInterface;
01996
01997 #ifdef RIO_DEBUG1
01998 RioErr << "[CNetTcp - Construtor] Start" << endl;
01999 #endif
02000
02001
02002 m_ServerInstance = false;
02003 m_ReceiveTimeOut = 0;
02004 m_SendTimeOut = 0;
02005 m_ConnectionTimeOut = 0;
02006 m_TcpServerThreadId = 0;
02007 m_Started = false;
02008 m_TcpServerStarted = false;
02009 m_CancelThreads = false;
02010 m_LogRotation = NULL;
02011 m_TcpServerPort = 0;
02012 m_ServerAddress = NULL;
02013 m_AddressSize = 0;
02014 m_ClientIPAddress = NULL;
02015 m_ClientPorts = NULL;
02016
02017
02018
02019 pthread_mutex_init( &m_Mutex, NULL );
02020 pthread_cond_init( &m_Cond, NULL );
02021
02022 #ifdef RIO_DEBUG1
02023 RioErr << "[CNetTcp - Construtor] Finish" << endl;
02024 #endif
02025 }
02026
02027
02028 CNetTcp::~CNetTcp()
02029 {
02030 #ifdef RIO_DEBUG1
02031 TCPLOG << "[CNetTcp - Destrutor] Start" << endl;
02032 #endif
02033
02034
02035 if( m_Started )
02036 Stop();
02037
02038
02039 pthread_mutex_destroy( &m_Mutex );
02040 pthread_cond_destroy( &m_Cond );
02041
02042 #ifdef RIO_DEBUG1
02043 TCPLOG << "[CNetTcp - Destrutor] Finish" << endl;
02044 #endif
02045 }
02046
02047
02048 void CNetTcp::GetKey( int IP, int Port, char *Key )
02049 {
02050
02051
02052
02053
02054
02055
02056 in_addr ips;
02057
02058 #ifdef RIO_DEBUG1
02059 TCPLOG << "[CNetTcp - GetKey] Start" << endl;
02060 #endif
02061
02062
02063 ips.s_addr = IP;
02064
02065
02066 sprintf( Key, "%s.%u", inet_ntoa( ips ), ( unsigned int ) ntohs( Port ) );
02067
02068 #ifdef RIO_DEBUG2
02069 TCPLOG << "CNetTcp::GetKey Chave para o IP " << inet_ntoa( ips )
02070 << " e porta " << ntohs( Port ) << ": " << Key << endl;
02071 #endif
02072
02073 #ifdef RIO_DEBUG1
02074 TCPLOG << "[CNetTcp - GetKey] Finish" << endl;
02075 #endif
02076 }
02077
02078
02079
02080 RioResult CNetTcp::NewConnection( int IP, int Port, int Socket,
02081 CTcpConnection **TcpConnection )
02082 {
02083
02084 RioResult RioStatus;
02085
02086 #ifdef RIO_DEBUG2
02087
02088 in_addr ip;
02089
02090 ip.s_addr = IP;
02091 #endif
02092
02093
02094 try
02095 {
02096 *TcpConnection = new CTcpConnection( this, m_ServerInstance );
02097 }
02098 catch( bad_alloc& ba )
02099 {
02100 #ifdef RIO_DEBUG2
02101 TCPLOG << "CNetTcp::NewConnection erro de alocacao de memoria "
02102 << "(bad_alloc, error = " << ba.what() << ") ao criar um objeto "
02103 << "para a nova conexao associada ao IP " << inet_ntoa( ip )
02104 << ", a porta " << ntohs( Port ) << " e ao socket com a ID "
02105 << Socket << "." << endl;
02106 #endif
02107
02108 #ifdef RIO_DEBUG1
02109 TCPLOG << "[CNetTcp - NewConnection] Finish1" << endl;
02110 #endif
02111
02112 *TcpConnection = NULL;
02113
02114 return ERROR_NETTCP + ERROR_MEMORY;
02115 }
02116
02117
02118 RioStatus = ( *TcpConnection )->Initialize( IP, Port, Socket, m_IP,
02119 m_ConnectionTimeOut,
02120 m_LogRotation );
02121 if( FAILED( RioStatus ) )
02122 {
02123 #ifdef RIO_DEBUG2
02124 TCPLOG << "CNetTcp::NewConnection erro 0x" << hex << RioStatus << dec
02125 << " (" << GetErrorDescription( RioStatus ) << ") ao "
02126 << "inicializar o objeto da nova conexao associada ao IP "
02127 << inet_ntoa( ip ) << ", a porta " << ntohs( Port ) << " e ao "
02128 << "socket com a ID " << Socket << "." << endl;
02129 #endif
02130
02131 #ifdef RIO_DEBUG1
02132 TCPLOG << "[CNetTcp - NewConnection] Finish2" << endl;
02133 #endif
02134
02135
02136 delete *TcpConnection;
02137
02138 *TcpConnection = NULL;
02139
02140 return RioStatus;
02141 }
02142
02143 #ifdef RIO_DEBUG1
02144 TCPLOG << "[CNetTcp - NewConnection] Finish3" << endl;
02145 #endif
02146
02147 return S_OK;
02148 }
02149
02150
02151
02152
02153 RioResult CNetTcp::EnableConnection( CTcpConnection *TcpConnection )
02154 {
02155
02156 char StreamKey[ MAXHASHKEYSIZE ];
02157
02158 char *AuxStr;
02159
02160 int IP;
02161
02162 int Port;
02163
02164
02165 TTcpConnectionsIterator ConnectionIterator;
02166
02167 RioResult RioStatus;
02168
02169 #ifdef RIO_DEBUG2
02170
02171 in_addr ip;
02172 #endif
02173
02174 #ifdef RIO_DEBUG1
02175 TCPLOG << "[CNetTcp - EnableConnection] Start" << endl;
02176 #endif
02177
02178
02179 AuxStr = NULL;
02180
02181
02182 RioStatus = TcpConnection->GetIpAndPort( &IP, &Port );
02183 if( FAILED( RioStatus ) )
02184 {
02185 #ifdef RIO_DEBUG2
02186 TCPLOG << "CNetTcp::EnableConnection erro 0x" << hex << RioStatus << dec
02187 << " (" << GetErrorDescription( RioStatus ) << ") ao executar a "
02188 << "funcao GetIpAndPort de um objeto do tipo CTcpConnection."
02189 << endl;
02190 #endif
02191
02192 #ifdef RIO_DEBUG1
02193 TCPLOG << "[CNetTcp - EnableConnection] Finish1" << endl;
02194 #endif
02195
02196 return RioStatus;
02197 }
02198
02199 #ifdef RIO_DEBUG2
02200
02201 ip.s_addr = IP;
02202 #endif
02203
02204
02205 GetKey( IP, Port, StreamKey );
02206
02207
02208 pthread_mutex_lock( &m_Mutex );
02209
02210
02211 ConnectionIterator = m_TcpConnectionsMap.find( StreamKey );
02212 if( ConnectionIterator != m_TcpConnectionsMap.end() )
02213 {
02214 #ifdef RIO_DEBUG2
02215 TCPLOG << "CNetTcp::EnableConnection a chave " << StreamKey << " (IP = "
02216 << inet_ntoa( ip ) << ", Port=" << ntohs( Port ) << "). Ja "
02217 << "existe na hash!" << endl;
02218 #endif
02219
02220 #ifdef RIO_DEBUG1
02221 TCPLOG << "[CNetTcp - EnableConnection] Finish2" << endl;
02222 #endif
02223
02224 return ERROR_NETTCP + ERROR_UNEXPECTED;
02225 }
02226
02227
02228 try
02229 {
02230 #ifdef RIO_DEBUG2
02231 TCPLOG << "CNetTcp::EnableConnection Tentando inserir uma nova entrada "
02232 << "na hash m_TcpConnectionsMap com a chave " << StreamKey
02233 << " (IP = " << inet_ntoa( ip ) << ", Port=" << ntohs( Port )
02234 << "). Tamanho atual da hash e de " << m_TcpConnectionsMap.size()
02235 << "." << endl;
02236 #endif
02237
02238 AuxStr = new char[ strlen( StreamKey ) + 1 ];
02239
02240 strcpy( AuxStr, StreamKey );
02241
02242 m_TcpConnectionsMap[ AuxStr ] = TcpConnection;
02243
02244 #ifdef RIO_DEBUG2
02245 TCPLOG << "CNetTcp::EnableConnection a nova entrada na hash "
02246 << "m_TcpConnectionsMap com a chave " << StreamKey << " (IP = "
02247 << inet_ntoa( ip ) << ", Port=" << ntohs( Port ) << ") foi "
02248 << "inserida com sucesso. Novo tamanho da hash e de "
02249 << m_TcpConnectionsMap.size() << "." << endl;
02250 #endif
02251 }
02252 catch( bad_alloc& ba )
02253 {
02254
02255 pthread_mutex_unlock( &m_Mutex );
02256
02257
02258 if( AuxStr != NULL )
02259 delete[] AuxStr;
02260
02261 #ifdef RIO_DEBUG2
02262 TCPLOG << "CNetTcp::EnableConnection erro de alocacao de memoria ("
02263 << "bad_alloc, error = " << ba.what() << ") ao criar uma "
02264 << "entrada no mapa m_TcpStreamsMap para o novo stream com a "
02265 << "chave " << StreamKey << " (IP = " << inet_ntoa( ip )
02266 << ", Port=" << ntohs( Port ) << ")." << endl;
02267 #endif
02268
02269 #ifdef RIO_DEBUG1
02270 TCPLOG << "[CNetTcp - EnableConnection] Finish2" << endl;
02271 #endif
02272
02273 return ERROR_NETTCP + ERROR_MEMORY;
02274 }
02275
02276
02277 pthread_mutex_unlock( &m_Mutex );
02278
02279
02280 RioStatus = TcpConnection->EnableConnection();
02281 if( FAILED( RioStatus ) )
02282 {
02283 #ifdef RIO_DEBUG2
02284 TCPLOG << "CNetTcp::EnableConnection erro 0x" << hex << RioStatus << dec
02285 << " (" << GetErrorDescription( RioStatus ) << ") ao executar a "
02286 << "funcao EnableConnection de um objeto do tipo CTcpConnection."
02287 << endl;
02288 #endif
02289
02290 #ifdef RIO_DEBUG1
02291 TCPLOG << "[CNetTcp - EnableConnection] Finish3" << endl;
02292 #endif
02293
02294 return RioStatus;
02295 }
02296
02297 #ifdef RIO_DEBUG1
02298 TCPLOG << "[CNetTcp - EnableConnection] Finish4" << endl;
02299 #endif
02300
02301 return S_OK;
02302 }
02303
02304
02305
02306 CTcpConnection *CNetTcp::TcpAccept( int ClientSocket, int ClientIP,
02307 int ClientPort )
02308 {
02309
02310 CTcpConnection *TcpConnection;
02311
02312 struct timeval timeout;
02313
02314 SNetTcpClientData ClientData;
02315
02316 SNetTcpServerData ServerData;
02317
02318 RioResult RioStatus;
02319
02320
02321 char ConnectionID[ TCP_START_MESSAGE_SIZE + 1 ];
02322
02323
02324 int opt;
02325
02326 #ifdef RIO_DEBUG1
02327 TCPLOG << "[CNetTcp - TcpAccept] Start" << endl;
02328 #endif
02329
02330 #ifdef RIO_DEBUG2
02331 struct in_addr ip, ipc;
02332 ip.s_addr = ClientIP;
02333
02334 TCPLOG << "CNetTcp::TcpAccept ACCEPT vindo do cliente com "
02335 << "IP " << inet_ntoa( ip ) << " e porta " << ntohs( ClientPort )
02336 << "." << endl;
02337 #endif
02338
02339
02340
02341 if( fcntl( ClientSocket, F_SETFD, FD_CLOEXEC ) < 0 )
02342 {
02343 #ifdef RIO_DEBUG2
02344 TCPLOG << "CNetTcp::TcpAccept erro " << errno << " ("
02345 << strerror( errno ) << ") ao fazer o socket de um cliente ser "
02346 << "exclusivo ao processo que criou o objeto da classe CNetTcp."
02347 << endl;
02348 #endif
02349
02350 #ifdef RIO_DEBUG1
02351 TCPLOG << "[CNetTcp - TcpAccept] Finish1" << endl;
02352 #endif
02353
02354 return( NULL );
02355 }
02356
02357
02358
02359
02360
02361
02362
02363 opt = 1;
02364
02365 if( setsockopt( ClientSocket, IPPROTO_TCP, TCP_NODELAY, (char *) &opt,
02366 sizeof( int ) ) < 0 )
02367 {
02368 #ifdef RIO_DEBUG2
02369 TCPLOG << "CNetTcp::TcpAccept erro " << errno << " ("
02370 << strerror( errno ) << ") ao executar o setsockopt com o nivel "
02371 << "IPPROTO_TCP, opcao TCP_NODELAY." << endl;
02372 #endif
02373
02374 #ifdef RIO_DEBUG1
02375 TCPLOG << "[CNetTcp - TcpAccept] Finish2" << endl;
02376 #endif
02377
02378 return( NULL );
02379 }
02380
02381
02382
02383 timeout.tv_sec = m_ReceiveTimeOut / 1000;
02384 timeout.tv_usec = ( m_ReceiveTimeOut % 1000 ) * 1000;
02385
02386 if( setsockopt( ClientSocket, SOL_SOCKET, SO_RCVTIMEO, &timeout,
02387 sizeof( timeout ) ) < 0 )
02388 {
02389 TCPLOG << "CNetTCP::TcpAccept erro " << errno << " ("
02390 << strerror( errno ) << ") ao executar o setsockopt com o nivel "
02391 << "SOL_SOCKET e a opcao SO_RCVTIMEO." << endl;
02392 close( ClientSocket );
02393
02394 #ifdef RIO_DEBUG1
02395 TCPLOG << "[CNetTcp - TcpAccept] Finish3" << endl;
02396 #endif
02397
02398 return( NULL );
02399 }
02400
02401
02402
02403 timeout.tv_sec = m_SendTimeOut / 1000;
02404 timeout.tv_usec = ( m_SendTimeOut % 1000 ) * 1000;
02405
02406 if( setsockopt( ClientSocket, SOL_SOCKET, SO_SNDTIMEO, &timeout,
02407 sizeof( timeout ) ) < 0 )
02408 {
02409 TCPLOG << "CNetTCP::TcpAccept erro " << errno << " ("
02410 << strerror( errno ) << ") ao executar o setsockopt com o nivel "
02411 << "SOL_SOCKET e a opcao SO_SNDTIMEO." << endl;
02412
02413 #ifdef RIO_DEBUG1
02414 TCPLOG << "[CNetTcp - TcpAccept] Finish4" << endl;
02415 #endif
02416
02417 return( NULL );
02418 }
02419
02420
02421
02422
02423
02424
02425
02426
02427 memset( ConnectionID, 0, TCP_START_MESSAGE_SIZE + 1 );
02428 if( recv( ClientSocket, ConnectionID, TCP_START_MESSAGE_SIZE,
02429 TCP_FLAGS_RECEIVE ) < 0 )
02430 {
02431 #ifdef RIO_DEBUG2
02432 TCPLOG << "CNetTcp::TcpAccept erro " << errno << " ("
02433 << strerror( errno ) << ") ao receber o identificador da "
02434 << "conexao." << endl;
02435 #endif
02436
02437 #ifdef RIO_DEBUG1
02438 TCPLOG << "[CNetTcp - TcpAccept] Finish5" << endl;
02439 #endif
02440
02441 return( NULL );
02442 }
02443
02444
02445 if( strcmp( ConnectionID, TCP_START_MESSAGE ) != 0 )
02446 {
02447 #ifdef RIO_DEBUG2
02448 TCPLOG << "CNetTcp::TcpAccept recebido um identificador de conexao "
02449 << "invalido " << ConnectionID << ". O identificador deveria "
02450 << "ser " << TCP_START_MESSAGE << ". Fechando a conexao TCP "
02451 << "com o cliente." << endl;
02452 #endif
02453
02454 #ifdef RIO_DEBUG1
02455 TCPLOG << "[CNetTcp - TcpAccept] Finish6" << endl;
02456 #endif
02457
02458 return( NULL );
02459 }
02460
02461
02462 memset( &ClientData, 0, sizeof( ClientData ) );
02463 if( recv( ClientSocket, &ClientData, sizeof( ClientData ),
02464 TCP_FLAGS_RECEIVE ) < 0 )
02465 {
02466 #ifdef RIO_DEBUG2
02467 TCPLOG << "CNetTcp::TcpAccept erro " << errno << " ("
02468 << strerror( errno ) << ") ao receber as informacao do cliente."
02469 << endl;
02470 #endif
02471
02472 #ifdef RIO_DEBUG1
02473 TCPLOG << "[CNetTcp - TcpAccept] Finish7" << endl;
02474 #endif
02475
02476 return( NULL );
02477 }
02478
02479 #ifdef RIO_DEBUG2
02480 TCPLOG << "CNetTcp::TcpAccept O cliente "
02481 << ( ( ClientData.ConnectionCreated ) ? "tem" : "nao tem" )
02482 << " espaco no buffer para uma conexao." << endl;
02483 #endif
02484
02485 if( ClientData.ConnectionCreated )
02486 {
02487
02488 RioStatus = NewConnection( ClientData.IP, ClientData.Port,
02489 ClientSocket, &TcpConnection );
02490 if( FAILED( RioStatus ) )
02491 {
02492 #ifdef RIO_DEBUG2
02493 TCPLOG << "CNetTcp::TcpAccept erro 0x" << hex << RioStatus << dec
02494 << " (" << GetErrorDescription( RioStatus )
02495 << ") ao criar um objeto para a conexao do socket." << endl;
02496 #endif
02497 }
02498
02499 #ifdef RIO_DEBUG2
02500
02501
02502 if( TcpConnection != NULL )
02503 {
02504 ipc.s_addr = ClientData.IP;
02505 TCPLOG << "CNetTcp::TcpAccept criando uma nova conexao TCP: "
02506 << "socket = " << ClientSocket << ", IP TCP (Servidor) = "
02507 << inet_ntoa( ip ) << ", porta TCP (Servidor) = "
02508 << ntohs( ClientPort ) << ", IP TCP (Cliente) = "
02509 << inet_ntoa( ipc ) << ", porta TCP (Cliente) = "
02510 << ntohs( ClientData.Port ) << "." << endl;
02511 }
02512 #endif
02513 }
02514 else
02515 {
02516
02517 TcpConnection = NULL;
02518
02519 #ifdef RIO_DEBUG2
02520 TCPLOG << "CNetTcp::TcpAccept nao existe espaco para criar um objeto "
02521 << "de conexao no cliente com o IP = " << inet_ntoa( ip )
02522 << " e a porta " << ntohs( ClientPort ) << endl;
02523 #endif
02524 }
02525
02526
02527 memset( &ServerData, 0, sizeof( ServerData ) );
02528 ServerData.ConnectionCreated = ( TcpConnection != NULL );
02529
02530
02531 if( send( ClientSocket, &ServerData, sizeof( ServerData ),
02532 TCP_FLAGS_SENDDATA ) < 0 )
02533 {
02534 #ifdef RIO_DEBUG2
02535 TCPLOG << "CNetTcp::TcpAccept erro " << errno << " ("
02536 << strerror( errno ) << ") ao enviar a informacao de espaco "
02537 << "disponivel no servidor para criar conexoes" << endl;
02538 #endif
02539
02540
02541 if( TcpConnection != NULL )
02542 {
02543
02544 RioStatus = TcpConnection->CancelConnection();
02545 #ifdef RIO_DEBUG2
02546 TCPLOG << "CNetTcp::TcpAccept erro 0x" << hex << RioStatus << dec
02547 << " (" << GetErrorDescription( RioStatus ) << ") ao "
02548 << "executar a funcao CancelConnection sobre o objeto da "
02549 << "conexao TcpConnection." << endl;
02550
02551 #endif
02552
02553 delete TcpConnection;
02554 }
02555
02556 #ifdef RIO_DEBUG1
02557 TCPLOG << "[RioNeti - TcpAccept] Finish8" << endl;
02558 #endif
02559
02560 return( NULL );
02561 }
02562
02563 if( TcpConnection == NULL )
02564 {
02565
02566 #ifdef RIO_DEBUG2
02567 TCPLOG << "CNetTcp::TcpAccept Erro ao se conectar ao cliente. Nao "
02568 << "existe espaco para criar um objeto de conexao para o "
02569 << "cliente" << endl;
02570 #endif
02571
02572 #ifdef RIO_DEBUG1
02573 TCPLOG << "[CNetTcp - TcpAccept] Finish9" << endl;
02574 #endif
02575
02576 return( NULL );
02577 }
02578
02579
02580
02581
02582 opt = 0;
02583
02584 if( setsockopt( ClientSocket, IPPROTO_TCP, TCP_NODELAY, (char *) &opt,
02585 sizeof( int ) ) < 0 )
02586 {
02587 #ifdef RIO_DEBUG2
02588 TCPLOG << "CNetTcp::TcpAccept erro " << errno << " ("
02589 << strerror( errno ) << ") ao executar o setsockopt com o nivel "
02590 << "IPPROTO_TCP, opcao TCP_NODELAY." << endl;
02591 #endif
02592
02593
02594 RioStatus = TcpConnection->CancelConnection();
02595 #ifdef RIO_DEBUG2
02596 TCPLOG << "CNetTcp::TcpAccept erro 0x" << hex << RioStatus << dec
02597 << " (" << GetErrorDescription( RioStatus ) << ") ao executar "
02598 << "a funcao CancelConnection sobre o objeto da conexao "
02599 << "TcpConnection." << endl;
02600
02601 #endif
02602
02603 delete TcpConnection;
02604
02605 #ifdef RIO_DEBUG1
02606 TCPLOG << "[CNetTcp - TcpAccept] Finish10" << endl;
02607 #endif
02608
02609 return( NULL );
02610 }
02611
02612
02613
02614
02615
02616 RioStatus = EnableConnection( TcpConnection );
02617 if( FAILED( RioStatus ) )
02618 {
02619 #ifdef RIO_DEBUG2
02620 TCPLOG << "CNetTcp::TcpAccept erro 0x" << hex << RioStatus << dec
02621 << " (" << GetErrorDescription( RioStatus )
02622 << ") ao ativar o objeto de conexao criado para o socket."
02623 << endl;
02624 #endif
02625
02626
02627 RioStatus = TcpConnection->CancelConnection();
02628 #ifdef RIO_DEBUG2
02629 TCPLOG << "CNetTcp::TcpAccept erro 0x" << hex << RioStatus << dec
02630 << " (" << GetErrorDescription( RioStatus ) << ") ao executar "
02631 << "a funcao CancelConnection sobre o objeto da conexao "
02632 << "TcpConnection." << endl;
02633
02634 #endif
02635
02636 delete TcpConnection;
02637
02638 #ifdef RIO_DEBUG1
02639 TCPLOG << "[CNetTcp - TcpAccept] Finish11" << endl;
02640 #endif
02641
02642 return( NULL );
02643 }
02644
02645 #ifdef RIO_DEBUG2
02646 TCPLOG << "CNetTcp::TcpAccept Conectei ao cliente." << endl;
02647 #endif
02648
02649 #ifdef RIO_DEBUG1
02650 TCPLOG << "[CNetTcp - TcpAccept] Finish12" << endl;
02651 #endif
02652
02653 return( TcpConnection );
02654 }
02655
02656
02657
02658 CTcpConnection *CNetTcp::TcpConnect( int ServerIP, int ServerPort,
02659 int *ClientIP, int *ClientPort )
02660 {
02661
02662 int ServerSocket;
02663
02664 CTcpConnection *TcpConnection;
02665
02666 struct timeval timeout;
02667
02668 SNetTcpClientData ClientData;
02669
02670 SNetTcpServerData ServerData;
02671
02672 RioResult RioStatus;
02673
02674 struct sockaddr_in ServerAddr;
02675
02676 struct sockaddr_in ClientAddr;
02677
02678
02679 socklen_t ClientAddrLen;
02680
02681
02682 int opt;
02683
02684 #ifdef RIO_DEBUG1
02685 TCPLOG << "[CNetTcp - TcpConnect] Start" << endl;
02686 #endif
02687
02688 #ifdef RIO_DEBUG2
02689 struct in_addr ip;
02690
02691 ip.s_addr = ServerIP;
02692 #endif
02693
02694
02695 if( ( ServerSocket = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
02696 {
02697 #ifdef RIO_DEBUG2
02698 TCPLOG << "CNetTcp::TcpConnect erro " << errno << " ("
02699 << strerror( errno ) << ") ao criar o socket de conexao."
02700 << endl;
02701 #endif
02702
02703 RioErr << "[TcpConnect] erro " << errno << " (" << strerror( errno )
02704 << ") ao executar a funcao socket." << endl;
02705
02706 #ifdef RIO_DEBUG1
02707 TCPLOG << "[CNetTcp - TcpConnect] Finish1" << endl;
02708 #endif
02709
02710 return( NULL );
02711 }
02712
02713
02714
02715 if( fcntl( ServerSocket, F_SETFD, FD_CLOEXEC ) < 0 )
02716 {
02717 #ifdef RIO_DEBUG2
02718 TCPLOG << "CNetTcp::TcpConnect erro " << errno << " ("
02719 << strerror( errno ) << ") ao fazer o socket de um servidor ser "
02720 << "exclusivo ao processo que criou o objeto da classe CNetTcp."
02721 << endl;
02722 #endif
02723
02724 RioErr << "[TcpConnect] erro " << errno << " (" << strerror( errno )
02725 << ") ao executar o fcntl com as opcoes F_SETFD e a FD_CLOEXEC."
02726 << endl;
02727
02728
02729 shutdown( ServerSocket, SHUT_RDWR );
02730
02731
02732 close( ServerSocket );
02733
02734 #ifdef RIO_DEBUG1
02735 TCPLOG << "[CNetTcp - TcpAccept] Finish2" << endl;
02736 #endif
02737
02738 return( NULL );
02739 }
02740
02741
02742
02743
02744
02745
02746
02747 opt = 1;
02748
02749 if( setsockopt( ServerSocket, IPPROTO_TCP, TCP_NODELAY, (char *) &opt,
02750 sizeof( int ) ) < 0 )
02751 {
02752 RioErr << "[TcpConnect] erro " << errno << " (" << strerror( errno )
02753 << ") ao executar o setsockopt com o nivel IPPROTO_TCP e a "
02754 << "opcao TCP_NODELAY." << endl;
02755
02756
02757 shutdown( ServerSocket, SHUT_RDWR );
02758
02759
02760 close( ServerSocket );
02761
02762 #ifdef RIO_DEBUG1
02763 TCPLOG << "[CNetTcp - TcpConnect] Finish3" << endl;
02764 #endif
02765
02766 return( NULL );
02767 }
02768
02769
02770 memset( &ServerAddr, 0, sizeof( ServerAddr ) );
02771
02772 ServerAddr.sin_family = AF_INET;
02773 ServerAddr.sin_addr.s_addr = ServerIP;
02774 ServerAddr.sin_port = ServerPort;
02775
02776 #ifdef RIO_DEBUG2
02777 TCPLOG << "CNetTcp::TcpConnect vou tentar conectar (connect) ao servidor "
02778 << "com o IP " << inet_ntoa( ip ) << " e a porta "
02779 << ntohs( ServerPort ) << endl;
02780 #endif
02781
02782
02783 if( connect( ServerSocket, ( struct sockaddr * ) &ServerAddr,
02784 sizeof( ServerAddr ) ) < 0 )
02785 {
02786 RioErr << "[TcpConnect] erro " << errno << " (" << strerror( errno )
02787 << ") ao conectar ao socket TCP." << endl;
02788
02789
02790 shutdown( ServerSocket, SHUT_RDWR );
02791
02792
02793 close( ServerSocket );
02794
02795 #ifdef RIO_DEBUG1
02796 TCPLOG << "[CNetTcp - TcpConnect] Finish4" << endl;
02797 #endif
02798
02799 return( NULL );
02800 }
02801
02802
02803
02804 timeout.tv_sec = m_ReceiveTimeOut / 1000;
02805 timeout.tv_usec = ( m_ReceiveTimeOut % 1000 ) * 1000;
02806
02807 if( setsockopt( ServerSocket, SOL_SOCKET, SO_RCVTIMEO, &timeout,
02808 sizeof( timeout ) ) < 0 )
02809 {
02810 RioErr << "[TcpConnect] erro " << errno << " (" << strerror( errno )
02811 << ") ao executar o setsockopt com o nivel SOL_SOCKET e a opcao "
02812 << "SO_RCVTIMEO." << endl;
02813
02814
02815 shutdown( ServerSocket, SHUT_RDWR );
02816
02817
02818 close( ServerSocket );
02819
02820 #ifdef RIO_DEBUG1
02821 TCPLOG << "[CNetTcp - TcpConnect] Finish5" << endl;
02822 #endif
02823
02824 return( NULL );
02825 }
02826
02827
02828
02829 timeout.tv_sec = m_SendTimeOut / 1000;
02830 timeout.tv_usec = ( m_SendTimeOut % 1000 ) * 1000;
02831
02832 if( setsockopt( ServerSocket, SOL_SOCKET, SO_SNDTIMEO, &timeout,
02833 sizeof( timeout ) ) < 0 )
02834 {
02835 RioErr << "[TcpConnect] erro " << errno << " (" << strerror( errno )
02836 << ") ao executar o setsockopt com o nivel SOL_SOCKET e a opcao "
02837 << "SO_SNDTIMEO." << endl;
02838
02839
02840 shutdown( ServerSocket, SHUT_RDWR );
02841
02842
02843 close( ServerSocket );
02844
02845 #ifdef RIO_DEBUG1
02846 TCPLOG << "[CNetTcp - TcpConnect] Finish6" << endl;
02847 #endif
02848
02849 return( NULL );
02850 }
02851
02852
02853
02854 if( send( ServerSocket, TCP_START_MESSAGE, TCP_START_MESSAGE_SIZE,
02855 TCP_FLAGS_SENDDATA ) < 0 )
02856 {
02857 RioErr << "[TcpConnect] erro " << errno << " (" << strerror( errno )
02858 << ") ao enviar o identificador da conexao " << TCP_START_MESSAGE
02859 << " ao servidor. " << endl;
02860
02861
02862 shutdown( ServerSocket, SHUT_RDWR );
02863
02864
02865 close( ServerSocket );
02866
02867 #ifdef RIO_DEBUG1
02868 TCPLOG << "[CNetTcp - TcpAccept] Finish7" << endl;
02869 #endif
02870
02871 return( NULL );
02872 }
02873
02874
02875 ClientAddrLen = sizeof( ClientAddr );
02876 if( getsockname( ServerSocket, (struct sockaddr *) &ClientAddr,
02877 &ClientAddrLen ) < 0 )
02878 {
02879 RioErr << "[TcpConnect] erro " << errno << " (" << strerror( errno )
02880 << ") ao obter as informacoes do socket." << endl;
02881
02882
02883 shutdown( ServerSocket, SHUT_RDWR );
02884
02885
02886 close( ServerSocket );
02887
02888 #ifdef RIO_DEBUG1
02889 TCPLOG << "[CNetTcp - TcpConnect] Finish8" << endl;
02890 #endif
02891
02892 return( NULL );
02893 }
02894
02895 RioStatus = NewConnection( ServerIP, ServerPort, ServerSocket,
02896 &TcpConnection );
02897 if( FAILED( RioStatus ) )
02898 {
02899 #ifdef RIO_DEBUG2
02900 TCPLOG << "CNetTcp::TcpConnect erro 0x" << hex << RioStatus << dec
02901 << " (" << GetErrorDescription( RioStatus )
02902 << ") ao criar um objeto para a conexao do socket." << endl;
02903 #endif
02904
02905 RioErr << "[TcpConnect] erro do RIO 0x" << hex << RioStatus << dec
02906 << " (" << GetErrorDescription( RioStatus ) << ") ao criar um "
02907 << "objeto para a conexao do socket." << endl;
02908
02909
02910 shutdown( ServerSocket, SHUT_RDWR );
02911
02912
02913 close( ServerSocket );
02914
02915 #ifdef RIO_DEBUG1
02916 TCPLOG << "[CNetTcp - TcpConnect] Finish9" << endl;
02917 #endif
02918
02919 return( NULL );
02920
02921 }
02922
02923 #ifdef RIO_DEBUG2
02924 if( TcpConnection != NULL )
02925 {
02926 TCPLOG << "CNetTcp::TcpConnect criando uma nova conexao TCP: socket = "
02927 << ServerSocket << ", IP TCP (Server) = " << inet_ntoa( ip )
02928 << ", porta TCP (Server) = " << ntohs( ServerPort )
02929 << ", IP TCP (Cliente) = " << inet_ntoa( ClientAddr.sin_addr )
02930 << ", porta TCP (Cliente) = " << ntohs( ClientAddr.sin_port )
02931 << "." << endl;
02932 }
02933 #endif
02934
02935
02936 memset( &ClientData, 0, sizeof( ClientData ) );
02937 ClientData.ConnectionCreated = ( TcpConnection != NULL );
02938 ClientData.IP = ClientAddr.sin_addr.s_addr;
02939 ClientData.Port = ClientAddr.sin_port;
02940
02941
02942 *ClientIP = ClientData.IP;
02943 *ClientPort = ClientData.Port;
02944
02945
02946 if( send( ServerSocket, &ClientData, sizeof( ClientData ),
02947 TCP_FLAGS_SENDDATA ) < 0 )
02948 {
02949 RioErr << "[TcpConnect] erro " << errno << " (" << strerror( errno )
02950 << ") ao enviar o dado com a informacao de se foi possivel "
02951 << "alocar um espaco para a conexao." << endl;
02952
02953
02954 if( TcpConnection != NULL )
02955 {
02956
02957 RioStatus = TcpConnection->CancelConnection();
02958 #ifdef RIO_DEBUG2
02959 TCPLOG << "CNetTcp::TcpConnect erro 0x" << hex << RioStatus << dec
02960 << " (" << GetErrorDescription( RioStatus ) << ") ao "
02961 << "executar a funcao CancelConnection sobre o objeto da "
02962 << "conexao TcpConnection." << endl;
02963
02964 #endif
02965
02966 delete TcpConnection;
02967 }
02968
02969
02970 shutdown( ServerSocket, SHUT_RDWR );
02971
02972
02973 close( ServerSocket );
02974
02975 #ifdef RIO_DEBUG1
02976 TCPLOG << "[CNetTcp - TcpConnect] Finish10" << endl;
02977 #endif
02978
02979 return( NULL );
02980 }
02981
02982
02983 memset( &ServerData, 0, sizeof( ServerData ) );
02984
02985 if( recv( ServerSocket, &ServerData, sizeof( ServerData ),
02986 TCP_FLAGS_RECEIVE ) < 0 )
02987 {
02988 TCPLOG << "[TcpConnect] erro " << errno << " (" << strerror( errno )
02989 << ") ao receber o dado com a informacao de se foi possivel "
02990 << "alocar um espaco para a conexao." << endl;
02991
02992
02993 if( TcpConnection != NULL )
02994 {
02995
02996 RioStatus = TcpConnection->CancelConnection();
02997 #ifdef RIO_DEBUG2
02998 TCPLOG << "CNetTcp::TcpConnect erro 0x" << hex << RioStatus << dec
02999 << " (" << GetErrorDescription( RioStatus ) << ") ao "
03000 << "executar a funcao CancelConnection sobre o objeto da "
03001 << "conexao TcpConnection." << endl;
03002
03003 #endif
03004
03005 delete TcpConnection;
03006 }
03007
03008
03009 shutdown( ServerSocket, SHUT_RDWR );
03010
03011
03012 close( ServerSocket );
03013
03014 #ifdef RIO_DEBUG1
03015 TCPLOG << "[CNetTcp - TcpConnect] Finish11" << endl;
03016 #endif
03017
03018 return( NULL );
03019 }
03020
03021 #ifdef RIO_DEBUG2
03022 TCPLOG << "CNetTcp::TcpConnect O servidor "
03023 << ( ( ServerData.ConnectionCreated ) ? "tem" : "nao tem" )
03024 << " espaco no buffer para a conexao." << endl;
03025 #endif
03026
03027
03028 if( ( ServerData.ConnectionCreated ) && ( TcpConnection != NULL ) )
03029 {
03030
03031
03032
03033 opt = 0;
03034
03035 if( setsockopt( ServerSocket, IPPROTO_TCP, TCP_NODELAY, (char *) &opt,
03036 sizeof( int ) ) < 0 )
03037 {
03038 #ifdef RIO_DEBUG2
03039 TCPLOG << "CNetTcp::TcpConnect erro " << errno << " ("
03040 << strerror( errno ) << ") ao executar o setsockopt com o "
03041 << "nivel IPPROTO_TCP, opcao TCP_NODELAY." << endl;
03042 #endif
03043
03044
03045 RioStatus = TcpConnection->CancelConnection();
03046 #ifdef RIO_DEBUG2
03047 TCPLOG << "CNetTcp::TcpConnect erro 0x" << hex << RioStatus << dec
03048 << " (" << GetErrorDescription( RioStatus ) << ") ao "
03049 << "executar a funcao CancelConnection sobre o objeto da "
03050 << "conexao TcpConnection." << endl;
03051
03052 #endif
03053
03054 delete TcpConnection;
03055
03056
03057 shutdown( ServerSocket, SHUT_RDWR );
03058
03059
03060 close( ServerSocket );
03061
03062 #ifdef RIO_DEBUG1
03063 TCPLOG << "[CNetTcp - TcpConnect] Finish12" << endl;
03064 #endif
03065
03066 return( NULL );
03067 }
03068
03069
03070
03071
03072
03073 RioStatus = EnableConnection( TcpConnection );
03074 if( FAILED( RioStatus ) )
03075 {
03076 #ifdef RIO_DEBUG2
03077 TCPLOG << "CNetTcp::TcpConnect erro 0x" << hex << RioStatus << dec
03078 << " (" << GetErrorDescription( RioStatus )
03079 << ") ao ativar o objeto de conexao criado para o socket."
03080 << endl;
03081 #endif
03082
03083
03084 RioStatus = TcpConnection->CancelConnection();
03085 #ifdef RIO_DEBUG2
03086 TCPLOG << "CNetTcp::TcpConnect erro 0x" << hex << RioStatus << dec
03087 << " (" << GetErrorDescription( RioStatus ) << ") ao "
03088 << "executar a funcao CancelConnection sobre o objeto da "
03089 << "conexao TcpConnection." << endl;
03090
03091 #endif
03092
03093 delete TcpConnection;
03094
03095 #ifdef RIO_DEBUG1
03096 TCPLOG << "[CNetTcp - TcpConnect] Finish13" << endl;
03097 #endif
03098
03099 return( NULL );
03100 }
03101
03102 #ifdef RIO_DEBUG2
03103 TCPLOG << "CNetTcp::TcpConnect Conectei ao servidor." << endl;
03104 #endif
03105
03106 #ifdef RIO_DEBUG1
03107 TCPLOG << "[CNetTcp - TcpConnect] Finish14" << endl;
03108 #endif
03109
03110 return( TcpConnection );
03111 }
03112 else
03113 {
03114
03115 if( TcpConnection != NULL )
03116 {
03117
03118 RioStatus = TcpConnection->CancelConnection();
03119 #ifdef RIO_DEBUG2
03120 TCPLOG << "CNetTcp::TcpConnect erro 0x" << hex << RioStatus << dec
03121 << " (" << GetErrorDescription( RioStatus ) << ") ao "
03122 << "executar a funcao CancelConnection sobre o objeto da "
03123 << "conexao TcpConnection." << endl;
03124
03125 #endif
03126
03127 delete TcpConnection;
03128 }
03129
03130 #ifdef RIO_DEBUG2
03131 TCPLOG << "CNetTcp::TcpConnect a conexao falhou pois nao existe espaco "
03132 << "no cliente e/ou no servidor para a conexao ser efetivada."
03133 << endl;
03134 #endif
03135
03136 RioErr << "[TcpConnect] a conexao falhou pois nao existe espaco para "
03137 << "um novo stream no outro lado da conexao." << endl;
03138
03139
03140 shutdown( ServerSocket, SHUT_RDWR );
03141
03142
03143 close( ServerSocket );
03144
03145 #ifdef RIO_DEBUG1
03146 TCPLOG << "[CNetTcp - TcpConnect] Finish15" << endl;
03147 #endif
03148
03149 return( NULL );
03150 }
03151 }
03152
03153
03154
03155 void CNetTcp::TcpServerThread( void )
03156 {
03157
03158 int ClientSocket;
03159
03160 struct sockaddr_in ServerAddr;
03161
03162 struct sockaddr_in ClientAddr;
03163
03164 socklen_t ClientAddrLen;
03165
03166
03167 CTcpConnection *TcpConnection;
03168
03169 #ifdef RIO_DEBUG1
03170 TCPLOG << "[CNetTcp - TcpServerThread] Start" << endl;
03171 #endif
03172
03173 RioErr << "TCPSERVERTHREADID " << syscall( SYS_gettid ) << endl;
03174
03175
03176 m_TcpServerStarted = false;
03177
03178
03179 if( ( m_TcpServerSocket = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
03180 {
03181 #ifdef RIO_DEBUG2
03182 TCPLOG << "CNetTcp::TcpServerThread erro " << errno << " ("
03183 << strerror( errno ) << ") ao criar o socket de escuta do TCP."
03184 << endl;
03185 #endif
03186 RioErr << "[CNetTcp] error when creating TCP socket: "
03187 << strerror( errno ) << endl;
03188
03189
03190 pthread_mutex_lock( &m_Mutex );
03191 pthread_cond_signal( &m_Cond );
03192 pthread_mutex_unlock( &m_Mutex );
03193
03194 #ifdef RIO_DEBUG1
03195 TCPLOG << "[CNetTcp - TcpServerThread] Finish1" << endl;
03196 #endif
03197
03198 return;
03199 }
03200
03201 memset( &ServerAddr, 0, sizeof( ServerAddr ) );
03202 ServerAddr.sin_family = AF_INET;
03203 ServerAddr.sin_port = m_TcpServerPort;
03204 ServerAddr.sin_addr.s_addr = m_IP;
03205
03206 if( bind( m_TcpServerSocket, ( struct sockaddr * ) &ServerAddr,
03207 sizeof( ServerAddr ) ) < 0 )
03208 {
03209 #ifdef RIO_DEBUG2
03210 TCPLOG << "CNetTcp::TcpServerThread erro " << errno << " ("
03211 << strerror( errno ) << ") no bind do socket de escuta do TCP."
03212 << endl;
03213 #endif
03214
03215 RioErr << "[CNetTcp] bind error in TCP socket: " << strerror( errno )
03216 << endl;
03217
03218
03219 pthread_mutex_lock( &m_Mutex );
03220 pthread_cond_signal( &m_Cond );
03221 pthread_mutex_unlock( &m_Mutex );
03222
03223 #ifdef RIO_DEBUG1
03224 TCPLOG << "[CNetTcp - TcpServerThread] Finish2" << endl;
03225 #endif
03226
03227 return;
03228 }
03229
03230 if( listen( m_TcpServerSocket, SOMAXCONN ) < 0 )
03231 {
03232 #ifdef RIO_DEBUG2
03233 TCPLOG << "CNetTcp::TcpServerThread erro " << errno << " ("
03234 << strerror( errno ) << ") no listen do socket de escuta do TCP."
03235 << endl;
03236 #endif
03237 RioErr << "[CNetTcp] listen error in TCP socket: " << strerror( errno )
03238 << endl;
03239
03240
03241 pthread_mutex_lock( &m_Mutex );
03242 pthread_cond_signal( &m_Cond );
03243 pthread_mutex_unlock( &m_Mutex );
03244
03245 #ifdef RIO_DEBUG1
03246 TCPLOG << "[CNetTcp - TcpServerThread] Finish3" << endl;
03247 #endif
03248
03249 return;
03250 }
03251
03252 TCPLOG << "[CNetTcp] esperando por clientes no IP "
03253 << inet_ntoa( ServerAddr.sin_addr ) << " e na porta "
03254 << ntohs( ServerAddr.sin_port ) << endl;
03255
03256
03257
03258 m_TcpServerStarted = true;
03259
03260
03261
03262 pthread_mutex_lock( &m_Mutex );
03263 pthread_cond_signal( &m_Cond );
03264 pthread_mutex_unlock( &m_Mutex );
03265
03266
03267 while( true )
03268 {
03269 ClientAddrLen = sizeof( ClientAddr );
03270
03271 #ifdef RIO_DEBUG2
03272 TCPLOG << "CNetTcp::TcpServerThread aceitando conexoes TCP de um "
03273 << "cliente " << endl;
03274 #endif
03275
03276
03277 if( ( ClientSocket = accept( m_TcpServerSocket,
03278 ( struct sockaddr * ) &ClientAddr,
03279 &ClientAddrLen ) ) < 0 )
03280 {
03281 if( ( errno == EBADF ) || ( errno != EINVAL ) )
03282 {
03283 #ifdef RIO_DEBUG2
03284 TCPLOG << "CNetTcp::TcpServerThread recebi o erro que a "
03285 << "o socket se tornou invalido (porque provavelmente "
03286 << "foi fechado. Terminando a thread!"<< endl;
03287 #endif
03288
03289 TCPLOG << "[TcpServerThread] Recebido erro EBADF ou EINVAL no "
03290 << "accept. Como isso ocorre somente ao finalizar o "
03291 << "servidor, a thread servidora sera finalizada!"
03292 << endl;
03293
03294 return;
03295 }
03296 #ifdef RIO_DEBUG2
03297 else if( errno != EINTR )
03298 TCPLOG << "CNetTcp::TcpServerThread recebi o erro que a "
03299 << "chamada ao sistena foi interrompida." << endl;
03300 else
03301 TCPLOG << "CNetTcp::TcpServerThread erro " << errno << " ("
03302 << strerror( errno ) << "ao executar o accept no "
03303 << "socket de escuta do TCP" << endl;
03304 #endif
03305 }
03306 else
03307 {
03308 #ifdef RIO_DEBUG2
03309 TCPLOG << "CNetTcp::TcpServerThread processando um pedido de "
03310 << "conexao recebido de um cliente!" << endl;
03311 #endif
03312
03313
03314 TcpConnection = TcpAccept( ClientSocket,
03315 ClientAddr.sin_addr.s_addr,
03316 ntohs( ClientAddr.sin_port ) );
03317
03318 if( TcpConnection == NULL )
03319 {
03320
03321
03322
03323 #ifdef RIO_DEBUG2
03324 TCPLOG << "CNetTcp::TcpServerThread erro ao criar o socket TCP"
03325 << endl;
03326 #endif
03327
03328
03329 shutdown( ClientSocket, SHUT_RDWR );
03330
03331
03332 close( ClientSocket );
03333 }
03334 else
03335 {
03336 #ifdef RIO_DEBUG2
03337 TCPLOG << "CNetTcp::TcpServerThread conexao TCP para um "
03338 << "cliente com o IP "
03339 << inet_ntoa( ClientAddr.sin_addr ) << " e a porta "
03340 << ntohs( ClientAddr.sin_port ) << " foi aceita e "
03341 << "criada (com um sokect cujo ID e " << ClientSocket
03342 << ")." << endl;
03343 #endif
03344 }
03345 }
03346
03347 }
03348
03349 #ifdef RIO_DEBUG1
03350 TCPLOG << "[CNetTcp - TcpServerThread] Finish5" << endl;
03351 #endif
03352
03353 return;
03354 }
03355
03356
03357
03358
03359 void *CNetTcp::TcpServerThreadEp( void *ThreadParam )
03360 {
03361 CNetTcp *NetTcp = ( CNetTcp * ) ThreadParam;
03362
03363 #ifdef RIO_DEBUG1
03364 TCPLOGEST << "[CNetTcp - TcpServerThreadEp] Start" << endl;
03365 #endif
03366
03367 NetTcp->TcpServerThread();
03368
03369 #ifdef RIO_DEBUG1
03370 TCPLOGEST << "[CNetTcp - TcpServerThreadEp] Finish" << endl;
03371 #endif
03372
03373 return 0;
03374 }
03375
03376
03377 RioResult CNetTcp::SendDataPrivate( CTcpConnection *TcpConnection, char *Data,
03378 unsigned int DataSize, void *Param )
03379 {
03380
03381
03382 RioResult RioStatus;
03383
03384 unsigned int SendDataSize;
03385
03386 #ifdef RIO_DEBUG1
03387 TCPLOG << "[CNetTcp - SendDataPrivate] Start" << endl;
03388 #endif
03389
03390 #ifdef RIO_DEBUG2
03391
03392 int IP;
03393
03394 int Port;
03395
03396 struct in_addr ip;
03397
03398
03399 RioStatus = TcpConnection->GetIpAndPort( &IP, &Port );
03400 if( FAILED( RioStatus ) )
03401 {
03402 #ifdef RIO_DEBUG2
03403 TCPLOG << "CNetTcp::SendDataPrivate erro 0x" << hex << RioStatus << dec
03404 << " (" << GetErrorDescription( RioStatus ) << ") ao executar a "
03405 << "funcao GetIpAndPort de um objeto do tipo CTcpConnection."
03406 << endl;
03407 #endif
03408
03409 #ifdef RIO_DEBUG1
03410 TCPLOG << "[CNetTcp - SendDataPrivate] Finish0" << endl;
03411 #endif
03412
03413 return RioStatus;
03414 }
03415
03416
03417 ip.s_addr = IP;
03418 #endif
03419
03420
03421
03422 RioStatus = TcpConnection->PutSendData( Data, DataSize, Param,
03423 &SendDataSize );
03424
03425 if( FAILED( RioStatus ) )
03426 {
03427 #ifdef RIO_DEBUG2
03428 TCPLOG << "CNetTcp::SendDataPrivate erro 0x" << hex << RioStatus
03429 << dec << " (" << GetErrorDescription( RioStatus ) << ") ao "
03430 << "executar a funcao PutSendData do objeto TcpConnection "
03431 << "(da classe CTcpConnection. Nao foi possivel enviar o "
03432 << "pacote para o IP " << inet_ntoa( ip ) << " e a porta "
03433 << ntohs( Port ) << endl;
03434 #endif
03435
03436 #ifdef RIO_DEBUG1
03437 TCPLOG << "[CNetTcp - SendDataPrivate] Finish1" << endl;
03438 #endif
03439
03440 return RioStatus;
03441 }
03442
03443 #ifdef RIO_DEBUG2
03444 TCPLOG << "CNetTcp::SendDataPrivate dados colocados com sucesso na "
03445 << "fila do objeto associado ao IP " << inet_ntoa( ip )
03446 << " e a porta " << ntohs( Port ) << ", para serem "
03447 << "futuramente enviados." << endl;
03448 #endif
03449
03450 #ifdef RIO_DEBUG1
03451 TCPLOG << "[CNetTcp - SendDataPrivate] Finish2" << endl;
03452 #endif
03453
03454 return S_OK;
03455 }
03456
03457
03458
03459 RioResult CNetTcp::CloseAllConnections()
03460 {
03461
03462 RioResult RioStatus;
03463
03464
03465 TTcpConnectionsIterator ConnectionIterator;
03466
03467
03468 CTcpConnection *TcpConnection;
03469
03470
03471 int IP;
03472
03473 int Port;
03474
03475 #ifdef RIO_DEBUG2
03476
03477 struct in_addr ip;
03478 #endif
03479
03480 #ifdef RIO_DEBUG1
03481 TCPLOG << "[CNetTcp - CloseAllConnections] Start" << endl;
03482 #endif
03483
03484
03485
03486 pthread_mutex_lock( &m_Mutex );
03487
03488 for( ConnectionIterator = m_TcpConnectionsMap.begin();
03489 ConnectionIterator != m_TcpConnectionsMap.end(); ConnectionIterator++ )
03490 {
03491
03492 TcpConnection = ( *ConnectionIterator ).second;
03493
03494
03495
03496
03497 RioStatus = TcpConnection->GetIpAndPort( &IP, &Port );
03498 if( FAILED( RioStatus ) )
03499 {
03500 #ifdef RIO_DEBUG2
03501 TCPLOG << "CNetTcp::CloseAllConnections erro 0x" << hex << RioStatus
03502 << dec << " (" << GetErrorDescription( RioStatus ) << ") ao "
03503 << "executar a funcao GetIpAndPort de um objeto do tipo "
03504 << "CTcpConnection." << endl;
03505 #endif
03506
03507 #ifdef RIO_DEBUG1
03508 TCPLOG << "[CNetTcp - CloseAllConnections] Finish1" << endl;
03509 #endif
03510
03511 return RioStatus;
03512 }
03513
03514 #ifdef RIO_DEBUG2
03515
03516
03517 ip.s_addr = IP;
03518
03519 TCPLOG << "CNetTcp::CloseAllConnections tentando finalizar a "
03520 << "conexao TCP para o IP "<< inet_ntoa( ip ) << " e a "
03521 << "porta " << ntohs( Port ) << endl;
03522 #endif
03523
03524
03525
03526 RioStatus = SendDataPrivate( TcpConnection, NULL, 0,
03527 ( void * ) NULLTRANSFERID );
03528 if( FAILED( RioStatus ) )
03529 {
03530 #ifdef RIO_DEBUG2
03531 TCPLOG << "CNetTcp::CloseAllConnections erro ao finalizar a "
03532 << "conexao TCP para o IP "<< inet_ntoa( ip ) << " e a "
03533 << "porta " << ntohs( Port ) << endl;
03534 #endif
03535
03536
03537
03538 m_NetInterface->ProcessError( IP, Port, RioStatus,
03539 "CloseAllConnections-SendDataPrivate",
03540 SENDERROR,
03541 ( void * ) NULLTRANSFERID );
03542 }
03543 }
03544
03545
03546
03547
03548 if( !m_TcpConnectionsMap.empty() )
03549 pthread_cond_wait( &m_Cond, &m_Mutex );
03550
03551
03552 pthread_mutex_unlock( &m_Mutex );
03553
03554 #ifdef RIO_DEBUG1
03555 TCPLOG << "[CNetTcp - CloseAllConnections] Finish2" << endl;
03556 #endif
03557
03558 return S_OK;
03559 }
03560
03561
03562
03563 RioResult CNetTcp::Start( SNetTcpConfig *NetConfig )
03564 {
03565 #ifdef RIO_DEBUG1
03566 TCPLOG << "[CNetTcp - Start] Start" << endl;
03567 #endif
03568
03569
03570 if( m_Started )
03571 {
03572 #ifdef RIO_DEBUG2
03573 TCPLOG << "CNetTcp::Start o objeto ja foi inicializado." << endl;
03574 #endif
03575
03576 #ifdef RIO_DEBUG1
03577 TCPLOG << "[CNetTcp - Start] Finish1" << endl;
03578 #endif
03579
03580 return ERROR_NETTCP + ERROR_STARTED;
03581 }
03582
03583
03584 m_ReceiveTimeOut = NetConfig->ReceiveTimeOut;
03585 m_SendTimeOut = NetConfig->SendTimeOut;
03586 m_ConnectionTimeOut = NetConfig->ConnectionTimeOut;
03587 m_ServerInstance = NetConfig->isServer;
03588 m_IP = NetConfig->HostIP;
03589
03590
03591 if( m_ServerInstance )
03592 {
03593
03594
03595
03596
03597 pthread_attr_t attribTcpServerThread;
03598
03599
03600
03601 bool TcpServerStarted;
03602
03603
03604 m_TcpServerPort = NetConfig->ServerPort;
03605 m_LogRotation = NetConfig->LogRotation;
03606
03607
03608
03609 m_ClientIPAddress = NULL;
03610 m_ClientPorts = NULL;
03611 m_ServerAddress = NULL;
03612 m_AddressSize = 0;
03613
03614
03615
03616 pthread_attr_init( &attribTcpServerThread );
03617 pthread_attr_setstacksize( &attribTcpServerThread,
03618 2 * PTHREAD_STACK_MIN );
03619
03620
03621
03622 pthread_mutex_lock( &m_Mutex );
03623
03624
03625 if ( pthread_create( &m_TcpServerThreadId, &attribTcpServerThread,
03626 TcpServerThreadEp, this ) != 0 )
03627 {
03628
03629 pthread_mutex_unlock( &m_Mutex );
03630
03631 #ifdef RIO_DEBUG2
03632 TCPLOG << "CNetTcp::Start erro " << errno << " ("
03633 << strerror( errno ) << ") ao criar a thread "
03634 << "TcpServerThread." << endl;
03635 #endif
03636
03637 #ifdef RIO_DEBUG1
03638 TCPLOG << "[CNetTcp - Start] Finish2" << endl;
03639 #endif
03640
03641 return ERROR_NETTCP + ERROR_CREATE_THREAD;
03642 }
03643
03644 #ifdef RIO_DEBUG2
03645 TCPLOG << "CNetTcp::Start antes de esperar a therad servidora do TCP "
03646 << "inicializar (com ou sem sucesso)." << endl;
03647 #endif
03648
03649
03650
03651 pthread_cond_wait( &m_Cond, &m_Mutex );
03652
03653 #ifdef RIO_DEBUG2
03654 TCPLOG << "CNetTcp::Start depois de esperar a therad servidora do TCP "
03655 << "inicializar. A thread "
03656 << ( ( m_TcpServerStarted ) ? "iniciazou" : "nao inicializou" )
03657 << " corretamente!" << endl;
03658 #endif
03659
03660
03661
03662 TcpServerStarted = m_TcpServerStarted;
03663
03664
03665 pthread_mutex_unlock( &m_Mutex );
03666
03667 if( !TcpServerStarted )
03668 {
03669 #ifdef RIO_DEBUG2
03670 TCPLOG << "CNetTcp::Start erro ao inicializar a thread "
03671 << "TcpServerThread." << endl;
03672 #endif
03673
03674
03675
03676 m_CancelThreads = true;
03677
03678 #ifdef RIO_DEBUG1
03679 TCPLOG << "[CNetTcp - Start] Finish3" << endl;
03680 #endif
03681
03682 return ERROR_NETTCP + ERROR_SOCKET_CONNECT;
03683 }
03684 }
03685 else
03686 {
03687
03688
03689
03690
03691
03692 CTcpConnection *TcpConnection;
03693
03694
03695
03696 int IP, Port;
03697
03698
03699 RioResult RioStatus;
03700
03701
03702
03703 bool isDispatcherConnectionCreated;
03704
03705
03706
03707 bool isStorageConnectionCreated;
03708
03709
03710
03711 m_TcpServerPort = 0;
03712 m_TcpServerThreadId = 0;
03713
03714
03715
03716
03717 isDispatcherConnectionCreated = false;
03718 isStorageConnectionCreated = false;
03719
03720
03721
03722 m_ServerAddress = NetConfig->ServerAddress;
03723 m_AddressSize = NetConfig->ServerAddressSize;
03724
03725
03726
03727 try
03728 {
03729 m_ClientIPAddress = new int[ m_AddressSize ];
03730 }
03731 catch( bad_alloc& ba )
03732 {
03733
03734
03735 #ifdef RIO_DEBUG2
03736 TCPLOG << "CNetTcp::Start erro de alocacao de memoria (bad_alloc,"
03737 << "error = " << ba.what() << ") ao criar a estrutura "
03738 << "m_ClientIPAddress." << endl;
03739 #endif
03740
03741 #ifdef RIO_DEBUG1
03742 TCPLOG << "[CNetTcp - Start] Finish4" << endl;
03743 #endif
03744
03745 return ERROR_NETTCP + ERROR_MEMORY;
03746
03747 }
03748
03749
03750
03751 try
03752 {
03753 m_ClientPorts = new int[ m_AddressSize ];
03754 }
03755 catch( bad_alloc& ba )
03756 {
03757
03758
03759
03760 delete[] m_ClientIPAddress;
03761
03762 #ifdef RIO_DEBUG2
03763 TCPLOG << "CNetTcp::Start erro de alocacao de memoria (bad_alloc,"
03764 << "error = " << ba.what() << ") ao criar a estrutura "
03765 << "m_ClientPorts." << endl;
03766 #endif
03767
03768 #ifdef RIO_DEBUG1
03769 TCPLOG << "[CNetTcp - Start] Finish5" << endl;
03770 #endif
03771
03772 return ERROR_NETTCP + ERROR_MEMORY;
03773
03774 }
03775
03776
03777 for( unsigned int i = 0; i < m_AddressSize; i++ )
03778 {
03779
03780
03781 TcpConnection = TcpConnect( m_ServerAddress[ i ].sin_addr.s_addr,
03782 m_ServerAddress[ i ].sin_port,
03783 &IP, &Port );
03784 if( TcpConnection == NULL )
03785 {
03786
03787
03788 #ifdef RIO_DEBUG2
03789 TCPLOG << "CNetTcp::Start erro ao criar a conexao TCP para o IP"
03790 << inet_ntoa( m_ServerAddress[ i ].sin_addr )
03791 << " a a porta "
03792 << ntohs( m_ServerAddress[ i ].sin_port ) << endl;
03793 #endif
03794
03795
03796 m_ClientIPAddress[ i ] = -1;
03797 m_ClientPorts[ i ] = 0;
03798 }
03799 else
03800 {
03801
03802
03803 m_ClientIPAddress[ i ] = IP;
03804 m_ClientPorts[ i ] = Port;
03805
03806
03807
03808
03809
03810 if( i == 0 )
03811 isDispatcherConnectionCreated = true;
03812 else
03813 isStorageConnectionCreated = true;
03814 }
03815
03816 #ifdef RIO_DEBUG2
03817
03818 in_addr ip;
03819
03820 if( ( m_ClientIPAddress[ i ] != -1 ) &&
03821 ( m_ClientPorts[ i ] != 0 ) )
03822 {
03823 TCPLOG << "CNetTcp::Start o cliente estabeleceu uma conexao "
03824 << "TCP com o servidor da posicao " << i << " do vetor "
03825 << "cujo IP e igual a "
03826 << inet_ntoa( m_ServerAddress[ i ].sin_addr )
03827 << " e cuja porta e igual a "
03828 << ntohs( m_ServerAddress[ i ].sin_port );
03829 fflush( stderr );
03830 ip.s_addr = m_ClientIPAddress[ i ];
03831 TCPLOG << ". A conexao foi associada ao IP " << inet_ntoa( ip )
03832 << " e a porta " << ntohs( m_ClientPorts[ i ] ) << "."
03833 << endl;
03834 }
03835 else
03836 {
03837 TCPLOG << "CNetTcp::Start o cliente nao consegui estabelecer "
03838 << "uma conexao TCP com o servidor da posicao " << i
03839 << " do vetor cujo IP e com o igual a "
03840 << inet_ntoa( m_ServerAddress[ i ].sin_addr )
03841 << " e cuja porta e igual a "
03842 << ntohs( m_ServerAddress[ i ].sin_port ) << "." << endl;
03843 }
03844 #endif
03845 }
03846
03847
03848
03849 if( ( !isDispatcherConnectionCreated ) ||
03850 ( !isStorageConnectionCreated ) )
03851 {
03852
03853 RioStatus = CloseAllConnections();
03854 #ifdef RIO_DEBUG2
03855 if( FAILED( RioStatus ) )
03856 {
03857 TCPLOG << "CNetTcp::Start erro 0x" << hex << RioStatus
03858 << dec << " (" << GetErrorDescription( RioStatus )
03859 << ") ao finalizar as conexoes TCP que foram "
03860 << "criadas com sucesso." << endl;
03861 }
03862 #endif
03863
03864
03865 delete[] m_ClientIPAddress;
03866
03867
03868 delete[] m_ClientPorts;
03869
03870 #ifdef RIO_DEBUG1
03871 TCPLOG << "[CNetTcp - Start] Finish6" << endl;
03872 #endif
03873
03874 return ERROR_NETTCP + ERROR_SOCKET_CONNECT;
03875 }
03876 }
03877
03878
03879
03880 m_Started = true;
03881
03882 #ifdef RIO_DEBUG2
03883 TCPLOG << "CNetTcp::Start objeto inicializado com sucesso!" << endl;
03884 #endif
03885
03886 #ifdef RIO_DEBUG1
03887 TCPLOG << "[CNetTcp - Start] Finish7" << endl;
03888 #endif
03889
03890 return S_OK;
03891 }
03892
03893
03894
03895 RioResult CNetTcp::Stop()
03896 {
03897
03898 RioResult RioStatus;
03899
03900 #ifdef RIO_DEBUG1
03901 TCPLOG << "[CNetTcp - Stop] Start" << endl;
03902 #endif
03903
03904
03905 if( !m_Started )
03906 {
03907 #ifdef RIO_DEBUG2
03908 TCPLOG << "CNetTcp::Stop o objeto nao foi inicializado." << endl;
03909 #endif
03910
03911 #ifdef RIO_DEBUG1
03912 TCPLOG << "[CNetTcp - Stop] Finish1" << endl;
03913 #endif
03914
03915 return ERROR_NETTCP + ERROR_NOT_STARTED;
03916 }
03917
03918
03919
03920 if( m_ServerInstance )
03921 {
03922
03923 shutdown( m_TcpServerSocket, SHUT_RDWR );
03924
03925 close( m_TcpServerSocket );
03926
03927 #ifdef RIO_DEBUG2
03928 TCPLOG << "CNetTcp::Stop Antes de executar pthread_cancel para a thread "
03929 << "com a ID " << m_TcpServerThreadId << "." << endl;
03930 #endif
03931
03932
03933
03934 pthread_join( m_TcpServerThreadId, NULL );
03935
03936 #ifdef RIO_DEBUG2
03937 TCPLOG << "CNetTcp::Stop Depois de executar pthread_cancel para a thread "
03938 << "com a ID " << m_TcpServerThreadId << "." << endl;
03939 #endif
03940 }
03941
03942
03943 RioStatus = CloseAllConnections();
03944 if( FAILED( RioStatus ) )
03945 {
03946 #ifdef RIO_DEBUG2
03947 TCPLOG << "CNetTcp::Stop erro 0x" << hex << RioStatus << dec << " ("
03948 << GetErrorDescription( RioStatus ) << "ao fechar as conexoes "
03949 << "TCP ativas!" << endl;
03950 #endif
03951
03952 #ifdef RIO_DEBUG1
03953 TCPLOG << "[CNetTcp - Stop] Finish2" << endl;
03954 #endif
03955
03956 return RioStatus;
03957 }
03958
03959
03960
03961 if( !m_ServerInstance )
03962 {
03963
03964 if( m_ClientIPAddress != NULL )
03965 delete[] m_ClientIPAddress;
03966 m_ClientIPAddress = NULL;
03967
03968
03969 if( m_ClientPorts != NULL )
03970 delete[] m_ClientPorts;
03971 m_ClientPorts = NULL;
03972 }
03973
03974
03975
03976 m_Started = false;
03977
03978 #ifdef RIO_DEBUG2
03979 TCPLOG << "CNetTcp::Stop objeto parado com sucesso!" << endl;
03980 #endif
03981
03982 #ifdef RIO_DEBUG1
03983 TCPLOG << "[CNetTcp - Stop] Finish3" << endl;
03984 #endif
03985
03986 return S_OK;
03987 }
03988
03989
03990 RioResult CNetTcp::SendData( int DestIP, int DestPort, char *Data,
03991 unsigned int DataSize, void *Param )
03992 {
03993
03994
03995 RioResult RioStatus;
03996
03997 char StreamKey[ MAXHASHKEYSIZE ];
03998
03999
04000 TTcpConnectionsIterator ConnectionIterator;
04001
04002
04003 CTcpConnection *TcpConnection;
04004
04005 #ifdef RIO_DEBUG1
04006 TCPLOG << "[CNetTcp - SendData] Start" << endl;
04007 #endif
04008
04009 #ifdef RIO_DEBUG2
04010 struct in_addr ip;
04011
04012 ip.s_addr = DestIP;
04013 #endif
04014
04015
04016 if( !m_Started )
04017 {
04018 #ifdef RIO_DEBUG2
04019 TCPLOG << "CNetTcp::SendData o objeto nao foi inicializado. Nao foi "
04020 << "possivel enviar o pacote para o IP " << inet_ntoa( ip )
04021 << " e a porta " << ntohs( DestPort ) << endl;
04022 #endif
04023
04024 #ifdef RIO_DEBUG1
04025 TCPLOG << "[CNetTcp - SendData] Finish1" << endl;
04026 #endif
04027
04028 return ERROR_NETTCP + ERROR_NOT_STARTED;
04029 }
04030
04031
04032 GetKey( DestIP, DestPort, StreamKey );
04033
04034
04035 pthread_mutex_lock( &m_Mutex );
04036
04037
04038 ConnectionIterator = m_TcpConnectionsMap.find( StreamKey );
04039 if( ConnectionIterator == m_TcpConnectionsMap.end() )
04040 {
04041
04042 pthread_mutex_unlock( &m_Mutex );
04043
04044
04045
04046 #ifdef RIO_DEBUG2
04047 TCPLOG << "CNetTcp::SendData O par IP " << inet_ntoa( ip ) << ", porta "
04048 << ntohs( DestPort ) << " nao foi achado na hash "
04049 << "m_TcpConnectionsMap com os objetos das conexoes TCP ativas!"
04050 << endl;
04051 #endif
04052
04053 #ifdef RIO_DEBUG1
04054 TCPLOG << "[CNetTcp - SendData] Finish2" << endl;
04055 #endif
04056
04057 return ERROR_NETTCP + ERROR_HOST_NOTFOUND;
04058 }
04059
04060
04061 TcpConnection = ( *ConnectionIterator ).second;
04062
04063 RioStatus = SendDataPrivate( TcpConnection, Data, DataSize, Param );
04064 #ifdef RIO_DEBUG2
04065 if( FAILED( RioStatus ) )
04066 TCPLOG << "CNetTcp::SendData erro 0x" << hex << RioStatus << dec << " ("
04067 << GetErrorDescription( RioStatus ) << ") ao executar a funcao "
04068 << "SendDataPrivate." << endl;
04069 #endif
04070
04071
04072 pthread_mutex_unlock( &m_Mutex );
04073
04074 #ifdef RIO_DEBUG2
04075 TCPLOG << "CNetTcp::SendData dados colocados com sucesso no objeto "
04076 << "associado ao IP " << inet_ntoa( ip ) << ", a porta "
04077 << ntohs( DestPort ) << ", com a chave " << StreamKey << "." << endl;
04078 #endif
04079
04080 #ifdef RIO_DEBUG1
04081 TCPLOG << "[CNetTcp - SendData] Finish3" << endl;
04082 #endif
04083
04084 return RioStatus;
04085 }
04086
04087
04088
04089 RioResult CNetTcp::GetIPAndPort( int *IP, int *Port, unsigned int Server )
04090 {
04091 #ifdef RIO_DEBUG2
04092
04093 in_addr ip;
04094 #endif
04095
04096 #ifdef RIO_DEBUG1
04097 TCPLOG << "[CNetTcp - GetIPAndPort] Start" << endl;
04098 #endif
04099
04100
04101 if( !m_Started )
04102 {
04103 #ifdef RIO_DEBUG2
04104 TCPLOG << "CNetTcp::GetIPAndPort o objeto nao foi inicializado. Nao "
04105 << "foi possivel obter o par IP, Porta.";
04106 if( m_ServerInstance )
04107 TCPLOG << "." << endl;
04108 else
04109 TCPLOG << " associado ao servidor " << Server << "." << endl;
04110 #endif
04111
04112 #ifdef RIO_DEBUG1
04113 TCPLOG << "[CNetTcp - GetIPAndPort] Finish1" << endl;
04114 #endif
04115
04116 return ERROR_NETTCP + ERROR_NOT_STARTED;
04117 }
04118
04119 if( m_ServerInstance )
04120 {
04121
04122
04123 if( IP != NULL )
04124 *IP = m_IP;
04125 if( Port != NULL )
04126 *Port = m_TcpServerPort;
04127
04128 #ifdef RIO_DEBUG2
04129 TCPLOG << "CNetTcp::GetIPAndPort funcao executada com sucesso para um "
04130 << "objeto associadao a um servidor.";
04131 if( IP != NULL )
04132 {
04133 ip.s_addr = *IP;
04134 TCPLOG << " O IP retornado sera " << inet_ntoa( ip ) << ".";
04135 }
04136 if( Port != NULL )
04137 TCPLOG << " A porta retornada sera " << ntohs( *Port ) << ".";
04138 TCPLOG << endl;
04139 #endif
04140
04141 #ifdef RIO_DEBUG1
04142 TCPLOG << "[CNetTcp - GetIPAndPort] Finish2" << endl;
04143 #endif
04144
04145 return S_OK;
04146 }
04147 else
04148 {
04149
04150
04151 if( Server >= m_AddressSize )
04152 {
04153 #ifdef RIO_DEBUG2
04154 TCPLOG << "CNetTcp::GetIPAndPort o identificador do servidor "
04155 << Server << " nao e valido. Deveria estar entre 0 e "
04156 << m_AddressSize - 1 << " (numero de servidores menos 1)."
04157 << endl;
04158 #endif
04159
04160 #ifdef RIO_DEBUG1
04161 TCPLOG << "[CNetTcp - GetIPAndPort] Finish3" << endl;
04162 #endif
04163
04164 return ERROR_NETTCP + ERROR_INVALID_PARAM;
04165 }
04166
04167
04168 if( IP != NULL )
04169 *IP = m_ClientIPAddress[ Server ];
04170 if( Port != NULL )
04171 *Port = m_ClientPorts[ Server ];
04172
04173 #ifdef RIO_DEBUG2
04174 ip.s_addr = *IP;
04175 TCPLOG << "CNetTcp::GetIPAndPort funcao executada com sucesso para "
04176 << "o servidor com o ID " << Server << ".";
04177 if( IP != NULL )
04178 {
04179 ip.s_addr = *IP;
04180 TCPLOG << " O IP retornado sera " << inet_ntoa( ip ) << ".";
04181 }
04182 if( Port != NULL )
04183 TCPLOG << " A porta retornada sera " << ntohs( *Port ) << ".";
04184 TCPLOG << endl;
04185 #endif
04186
04187 #ifdef RIO_DEBUG1
04188 TCPLOG << "[CNetTcp - GetIPAndPort] Finish4" << endl;
04189 #endif
04190
04191 return S_OK;
04192 }
04193 }
04194
04195
04196
04197
04198
04199 RioResult CNetTcp::GetAllIPsAndPorts( int **IPs, int **Ports )
04200 {
04201 #ifdef RIO_DEBUG1
04202 TCPLOG << "[CNetTcp - GetAllIPsAndPorts] Start" << endl;
04203 #endif
04204
04205
04206 if( !m_Started )
04207 {
04208 #ifdef RIO_DEBUG2
04209 TCPLOG << "CNetTcp::GetAllIPsAndPorts o objeto nao foi inicializado. "
04210 << "Nao foi possivel obter os IPs e as portas." << endl;
04211 #endif
04212
04213 #ifdef RIO_DEBUG1
04214 TCPLOG << "[CNetTcp - GetAllIPsAndPorts] Finish1" << endl;
04215 #endif
04216
04217 *IPs = NULL;
04218 *Ports = NULL;
04219
04220 return ERROR_NETTCP + ERROR_NOT_STARTED;
04221 }
04222
04223
04224 if( m_ServerInstance )
04225 {
04226
04227
04228
04229
04230
04231 *IPs = &m_IP;
04232 *Ports = &m_TcpServerPort;
04233 }
04234 else
04235 {
04236
04237
04238 *IPs = m_ClientIPAddress;
04239 *Ports = m_ClientPorts;
04240 }
04241
04242 #ifdef RIO_DEBUG2
04243 TCPLOG << "CNetTcp::GetAllIPsAndPorts funcao executada foi executada com "
04244 << "sucesso e obteve os dois ponteiros, um para o vetor interno com "
04245 << "os IPs (" << *IPs << ") e um outro para o vetor interno com as "
04246 << "portas (" << *Ports << ")." << endl;
04247 #endif
04248
04249 #ifdef RIO_DEBUG1
04250 TCPLOG << "[CNetTcp - GetAllIPsAndPorts] Finish2" << endl;
04251 #endif
04252
04253 return S_OK;
04254 }
04255
04256
04257
04258 RioResult CNetTcp::FindIPAndPort( int IP, int Port, bool *isFound )
04259 {
04260
04261 char StreamKey[ MAXHASHKEYSIZE ];
04262
04263
04264 TTcpConnectionsIterator ConnectionIterator;
04265
04266 #ifdef RIO_DEBUG1
04267 TCPLOG << "[CNetTcp - FindIPAndPort] Start" << endl;
04268 #endif
04269
04270 #ifdef RIO_DEBUG2
04271 struct in_addr ip;
04272
04273 ip.s_addr = IP;
04274 #endif
04275
04276
04277 if( !m_Started )
04278 {
04279 #ifdef RIO_DEBUG2
04280 TCPLOG << "CNetTcp::FindIPAndPort o objeto nao foi inicializado. Nao "
04281 << "foi possivel verificar o par IP " << inet_ntoa( ip ) << " e "
04282 << "a porta " << ntohs( Port ) << "." << endl;
04283 #endif
04284
04285 #ifdef RIO_DEBUG1
04286 TCPLOG << "[CNetTcp - FindIPAndPort] Finish1" << endl;
04287 #endif
04288
04289 *isFound = false;
04290
04291 return ERROR_NETTCP + ERROR_NOT_STARTED;
04292 }
04293
04294
04295 GetKey( IP, Port, StreamKey );
04296
04297
04298 pthread_mutex_lock( &m_Mutex );
04299
04300
04301 ConnectionIterator = m_TcpConnectionsMap.find( StreamKey );
04302 *isFound = ( ConnectionIterator != m_TcpConnectionsMap.end() );
04303
04304
04305 pthread_mutex_unlock( &m_Mutex );
04306
04307 #ifdef RIO_DEBUG2
04308 TCPLOG << "CNetTcp::FindIPAndPort Funcao executada com sucesso para o "
04309 << "IP " << inet_ntoa( ip ) << " e a porta " << ntohs( Port )
04310 << "O par IP, porta " << ( ( *isFound ) ? "foi " : "nao foi " )
04311 << "achado na hash com as conexoes TCP ativas!" << endl;
04312 #endif
04313
04314 #ifdef RIO_DEBUG1
04315 TCPLOG << "[CNetTcp - FindIPAndPort] Finish2" << endl;
04316 #endif
04317
04318 return S_OK;
04319 }
04320
04321
04322
04323 void CNetTcp::setLogRotation( CLogRotation *LogRotation )
04324 {
04325 #ifdef RIO_DEBUG1
04326 TCPLOG << "[CNetTcp - setLogRotation] Start" << endl;
04327 #endif
04328
04329
04330 if( !m_Started )
04331 {
04332 #ifdef RIO_DEBUG2
04333 TCPLOG << "CNetTcp::setLogRotation o objeto nao foi inicializado. Nao "
04334 << "foi possivel setar o objeto de controle de logs." << endl;
04335 #endif
04336
04337 #ifdef RIO_DEBUG1
04338 TCPLOG << "[CNetTcp - setLogRotation] Finish1" << endl;
04339 #endif
04340
04341 return;
04342 }
04343
04344
04345
04346 m_LogRotation = LogRotation;
04347
04348 #ifdef RIO_DEBUG1
04349 TCPLOG << "[CNetTcp - setLogRotation] Finish2" << endl;
04350 #endif
04351
04352 }
04353
04354
04355
04356 void CNetTcp::ProcessData( int IP, int Port, char *Data, unsigned int DataSize )
04357 {
04358 #ifdef RIO_DEBUG1
04359 TCPLOG << "[CNetTcp - ProcessData] Start" << endl;
04360 #endif
04361
04362
04363 if( !m_Started )
04364 {
04365 #ifdef RIO_DEBUG2
04366 TCPLOG << "CNetTcp::ProcessData o objeto nao foi inicializado. Nao foi "
04367 << "possivel executar a funcao ProcessData." << endl;
04368 #endif
04369
04370 #ifdef RIO_DEBUG1
04371 TCPLOG << "[CNetTcp - ProcessData] Finish1" << endl;
04372 #endif
04373
04374 return;
04375 }
04376
04377
04378
04379 m_NetInterface->ProcessData( IP, Port, Data, DataSize );
04380
04381 #ifdef RIO_DEBUG1
04382 TCPLOG << "[CNetTcp - ProcessData] Finish2" << endl;
04383 #endif
04384 }
04385
04386
04387
04388 void CNetTcp::SendDataCompleted( int IP, int Port, void *Param )
04389 {
04390 #ifdef RIO_DEBUG1
04391 TCPLOG << "[CNetTcp - SendDataCompleted] Start" << endl;
04392 #endif
04393
04394
04395 if( !m_Started )
04396 {
04397 #ifdef RIO_DEBUG2
04398 TCPLOG << "CNetTcp::SendDataCompleted o objeto nao foi inicializado. "
04399 << "Nao foi possivel executar a funcao SendDataCompleted."
04400 << endl;
04401 #endif
04402
04403 #ifdef RIO_DEBUG1
04404 TCPLOG << "[CNetTcp - SendDataCompleted] Finish1" << endl;
04405 #endif
04406
04407 return;
04408 }
04409
04410
04411
04412 m_NetInterface->SendDataCompleted( IP, Port, Param );
04413
04414 #ifdef RIO_DEBUG1
04415 TCPLOG << "[CNetTcp - SendDataCompleted] Finish2" << endl;
04416 #endif
04417 }
04418
04419
04420 void CNetTcp::ProcessError( int IP, int Port, RioResult RioError,
04421 const char *Msg, EErrorType ErrorType, void *Param )
04422 {
04423 #ifdef RIO_DEBUG1
04424 TCPLOG << "[CNetTcp - ProcessError] Start" << endl;
04425 #endif
04426
04427
04428 if( !m_Started )
04429 {
04430 #ifdef RIO_DEBUG2
04431 TCPLOG << "CNetTcp::ProcessError o objeto nao foi inicializado. "
04432 << "Nao foi possivel executar a funcao ProcessError." << endl;
04433 #endif
04434
04435 #ifdef RIO_DEBUG1
04436 TCPLOG << "[CNetTcp - ProcessError] Finish1" << endl;
04437 #endif
04438
04439 return;
04440 }
04441
04442
04443
04444 m_NetInterface->ProcessError( IP, Port, RioError, Msg, ErrorType, Param );
04445
04446 #ifdef RIO_DEBUG1
04447 TCPLOG << "[CNetTcp - ProcessError] Finish2" << endl;
04448 #endif
04449 }
04450
04451
04452
04453 void CNetTcp::ConnectionClosed( int IP, int Port, EClosedType ClosedType )
04454 {
04455
04456 char StreamKey[ MAXHASHKEYSIZE ];
04457
04458
04459 const char *StrKey;
04460
04461
04462 TTcpConnectionsIterator ConnectionIterator;
04463
04464 #ifdef RIO_DEBUG1
04465 TCPLOG << "[CNetTcp - ConnectionClosed] Start" << endl;
04466 #endif
04467
04468
04469
04470
04471 if( !m_Started )
04472 {
04473 #ifdef RIO_DEBUG2
04474 TCPLOG << "CNetTcp::ConnectionClosed o objeto nao foi inicializado. "
04475 << "Nao foi possivel executar a funcao ConnectionClosed."
04476 << endl;
04477 #endif
04478
04479 #ifdef RIO_DEBUG1
04480 TCPLOG << "[CNetTcp - ConnectionClosed] Finish1" << endl;
04481 #endif
04482
04483 return;
04484 }
04485
04486
04487 m_NetInterface->ConnectionClosed( IP, Port, ClosedType );
04488
04489
04490 GetKey( IP, Port, StreamKey );
04491
04492
04493 pthread_mutex_lock( &m_Mutex );
04494
04495
04496
04497
04498 ConnectionIterator = m_TcpConnectionsMap.find( StreamKey );
04499 if( ConnectionIterator != m_TcpConnectionsMap.end() )
04500 {
04501
04502 StrKey = ( *ConnectionIterator).first;
04503
04504 m_TcpConnectionsMap.erase( ConnectionIterator );
04505
04506 delete[] StrKey;
04507
04508
04509
04510
04511 if( m_TcpConnectionsMap.empty() )
04512 pthread_cond_signal( &m_Cond );
04513 }
04514 #ifdef RIO_DEBUG2
04515 else
04516 {
04517
04518 in_addr ip;
04519
04520
04521 ip.s_addr = IP;
04522
04523
04524 TCPLOG << "CNetTcp::ConnectionClosed O par IP " << inet_ntoa( ip )
04525 << ", porta " << ntohs( Port ) << " nao foi achado na hash "
04526 << "m_TcpConnectionsMap com os objetos das conexoes TCP ativas!"
04527 << endl;
04528 }
04529 #endif
04530
04531
04532 pthread_mutex_unlock( &m_Mutex );
04533
04534 #ifdef RIO_DEBUG1
04535 TCPLOG << "[CNetTcp - ConnectionClosed] Finish2" << endl;
04536 #endif
04537 }