00001 /* 00002 * Copyright (C) 2010, Edmundo Albuquerque de Souza e Silva. 00003 * 00004 * This file may be distributed under the terms of the Q Public License 00005 * as defined by Trolltech AS of Norway and appearing in the file 00006 * LICENSE.QPL included in the packaging of this file. 00007 * 00008 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING 00009 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00010 * PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, 00011 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 00012 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 00013 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 00014 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 00015 * 00016 * Thanks: Jose Renato Santos 00017 * 00018 */ 00019 00020 /////////////////////////////////////////////////////////////////// 00021 // NetTcp.h: headers for NetTcp.cpp 00022 /////////////////////////////////////////////////////////////////// 00023 00024 #ifndef __NETTCP_H_ 00025 #define __NETTCP_H_ 00026 00027 // Unidades usadas do C++ 00028 #include <queue> 00029 #include <fstream> 00030 #include <ext/hash_map> 00031 00032 // Unidades usadas do C. 00033 #include <pthread.h> 00034 #include <sys/types.h> 00035 #include <string.h> 00036 00037 // Unidades uadas do RIO. 00038 #include "RioInterfaceTypes.h" 00039 #include "LogRotation.h" 00040 #include "RioUnix.h" 00041 00042 using namespace std; 00043 // Namespace para usar a extensao da STL (o hash_map). Devemos realmente usar 00044 // esta extensao? 00045 using namespace __gnu_cxx; 00046 00047 // Definicoes das classes para evitar erros. 00048 class CNetInterface; 00049 class CNetTcp; 00050 class CTcpConnection; 00051 00052 // Novas constantes usadas pela implementacao TCP 00053 // Flags usadas ao receber os dados via TCP. 00054 #define TCP_FLAGS_RECEIVE MSG_WAITALL 00055 // Flags usadas ao enviar o tamanho via TCP. 00056 #define TCP_FLAGS_SENDSIZE MSG_NOSIGNAL | MSG_MORE 00057 // Flags usadas ao enviar os dados via TCP. 00058 #define TCP_FLAGS_SENDDATA MSG_NOSIGNAL 00059 00060 // Novas constantes usadas pelo socket UDP usado para desbloquear o poll. 00061 // Flag usada ao receber a mensagem para desbloquear o poll. 00062 #define UDP_FLAGS_RECEIVE MSG_WAITALL 00063 // Flag usada ao enviar a mensagem para desbloquear o poll. 00064 #define UDP_FLAGS_SEND MSG_CONFIRM 00065 00066 // Mensagem enviada para o socket UDP para desbloquear a funcao poll. 00067 #define MSG_POLL_NEWDATA "NEW_DATA" 00068 #define MSG_POLL_SIZE 8 00069 00070 // Mensagem inicial que deve ser enviada pelo cliente para sabermos que estamos 00071 // usando a nova implementacao (o cliente da implementacao do TCP original, 00072 // comeca a conexao enviando 00001 se conseguir alocar uma entrada no mapa de 00073 // streams, ou 00000 caso nao consigua fazer esta alocacao). O que vamos fazer 00074 // e receber uma string tambem com tamanho 5 e, se ela for diferente de 00075 // TCP_START_MESSAGE (cuja mensagem nao e igual a 00000 ou 00001), a conexao 00076 // sera fechada e esperamos que, com esta atitude, o cliente derecte que a 00077 // conexao foi fechada ao executar o segundo send da conexao. 00078 #define TCP_START_MESSAGE_SIZE 5 00079 #define TCP_START_MESSAGE "NTCPI" // NITCP: New TCP Implementation. 00080 00081 // Define o tamanho maximo para a string da hash. O tamanho maximo necessario e 00082 // um pouco menor, 22, para a seguinte string mais o terminador: 00083 // iii.iii.iii.iii.ppppp, onde iii.iii.iii.iii e a representacao maximo para o 00084 // IP e ppppp e a representacao maxima para a porta. 00085 #define MAXHASHKEYSIZE 25 00086 00087 // Armazena o numero de sockets (que sao dois no momento, o TCP e o UDP usado 00088 // para desbloquear o comando poll) usada pela thread TcpNetMgrThread. 00089 #define TCPCONNECTIONSOCKETSNUMBER 2 00090 00091 // Armazena as entradas usadas pela estrutura do poll. 00092 #define TCPCONNECTIONSOCKETTCP 0 // Posicao do socket TCP. 00093 #define TCPCONNECTIONSOCKETUDP 1 // Posicao do socket UDP. 00094 00095 // Possiveis motivos para a conexao ter sido fechada. 00096 enum EClosedType 00097 { 00098 CONNECTIONCLOSEDLOCALLY, // A conexao foi fechada pelo proprio objeto. 00099 CONNECTIONCLOSEDREMOTELLY, // A conexao foi fechada pelo outro lado. 00100 CONNECTIONTIMEOUT, // A conexao foi fechada por timeout. 00101 CONNECTIONUNDEFINED // Usado para inicializar as variaveis. 00102 }; 00103 00104 // Tipos de erro para a funcao ProcessError da classe CNetInterface e da classe 00105 // CNetTcp (que, de fato, e passado a funcao da classe CNetInterface). 00106 enum EErrorType 00107 { 00108 RECEIVEERROR, 00109 SENDERROR, 00110 OTHERERROR 00111 }; 00112 00113 00114 // Estrutura usada para armazenar os dados a serem enviados por um socket 00115 // (ela e necessaria para simular o comportamento do servidor). 00116 typedef struct 00117 { 00118 char *Data; // Ponteiro para os dados. 00119 unsigned int DataSize; // Tamanho dos dados. 00120 void *Param; // Parametro a ser passado quando a funcao SendDataCompleted 00121 // do objeto da classe CNetInterface for chamada. 00122 } SSendData; 00123 00124 // Novo tipo que define uma fila com todos os dados a serem enviados por um 00125 // stream. 00126 typedef queue< SSendData > TSendQueue; 00127 00128 // Nova estrutura com uma funcao para comparar dois identificadores da hash 00129 // que armazena os identificadores. 00130 struct EqKeys 00131 { 00132 bool operator()( const char *ID1, const char *ID2 ) const 00133 { 00134 return ( strcmp( ID1, ID2 ) == 0 ); 00135 } 00136 }; 00137 00138 // Novo tipo de hash para o identificador de uma stream. 00139 typedef hash< const char * > TKeyHash; 00140 00141 // Novo tipo para armazenar as estruturas TcpStream, com uma busca eficiente 00142 //typedef map< unsigned long long int, TStreamID > TTcpStreamsMap; 00143 typedef hash_map< const char *, CTcpConnection *, TKeyHash, 00144 EqKeys > TTcpConnectionsMap; 00145 00146 // Novo tipo para armazenar um interador para a hash do tipo TTcpStreamsMap com 00147 // os objetos associados as conexoes TCP ativas. 00148 00149 typedef TTcpConnectionsMap::iterator TTcpConnectionsIterator; 00150 // Estruturas usadas para passar as informacoes a funcao Start da classe 00151 // abstrata CNet. 00152 00153 // Estrutura de configuracao do TCP 00154 typedef struct 00155 { 00156 bool isServer; // Define se e um cliente ou um dos servidores (usado para 00157 // criar a thread servidora do TCP). 00158 // Campos usados pelo cliente e pelo servidor. 00159 unsigned int ReceiveTimeOut; // Tempo maximo (em milisegundos) de espera em 00160 // cada reveice. 00161 unsigned int SendTimeOut; // Tempo maximo (em milisegundos) de espera em 00162 // cada send. 00163 time_t ConnectionTimeOut; // Tempo maximo (em segundos) de inatividade 00164 // (sem transmissao de dados) de uma das conexoes 00165 // TCP. 00166 int HostIP; // Endereco IP da maquina associada ao cliente/servidor/storage. 00167 #ifdef RIO_DEBUG_FILE 00168 const char *LogFileName; // Nome do arquivo que armazenara os logs. 00169 #endif 00170 // Campos usados pelo cliente 00171 struct sockaddr_in *ServerAddress; // Vetor com os enderecos (IP, 00172 // porta) dos servidores 00173 unsigned int ServerAddressSize; // Numero de servidores no vetor acima. 00174 // Campos usados pelo servidor e pelo storage. 00175 int ServerPort; // Porta TCP do servidor/storage. 00176 CLogRotation *LogRotation; // Ponteiro para um objeto da classe de 00177 // gerenciamento dos logs de envio de dados. 00178 } SNetTcpConfig; 00179 00180 // Estrutura enviada pelo cliente ao servidor durante o estabelecimento uma 00181 // conexao TCP. 00182 typedef struct 00183 { 00184 bool ConnectionCreated; // Informa se o cliente conseguiu alocar (true) 00185 // ou nao (false) uma conexao. 00186 int IP; // Endereco IP da conexao TCP no cliente. 00187 int Port; // Porta da conexao TCP no cliente. 00188 } SNetTcpClientData; 00189 00190 // Estrutura enviada pelo servidor ao cliente durante o estabelecimento uma 00191 // conexao Tcp. 00192 typedef struct 00193 { 00194 bool ConnectionCreated; // Informa se o servidor conseguiu alocar (true) 00195 // ou nao (false) o stream. 00196 } SNetTcpServerData; 00197 00198 // Classe usada para gerenciar os streams da conexao TCP. 00199 class CTcpConnection 00200 { 00201 private: 00202 // Ponteiro para o objeto da classe CNetTCP que usa o stream. 00203 CNetTcp *m_NetTcp; 00204 // Indica se o objeto da classe foi inicializado. 00205 bool m_Initialized; 00206 // Define se a instancia da classe esta associada a um cliente (false) 00207 // ou a um servidor (true) 00208 bool m_ServerInstance; 00209 // Ponteiro para o objeto da classe de gerenciamento dos logs de envio 00210 // de dados (usado somente pelo servidor). 00211 CLogRotation *m_LogRotation; 00212 // IP associado ao socket. 00213 int m_IP; 00214 // Porta associada ao socket. 00215 int m_Port; 00216 // Socket da conexao TCP. 00217 int m_Socket; 00218 // Tempo em que o socket foi usado (leitura ou escrita) pela ultima vez 00219 // (medido em segundos desde a Epoch). 00220 time_t m_LastUseTime; 00221 // Armazena o tempo de timeout (em sehundos) de uma das conexoes TCP 00222 // principal. O timeout ocorrera somente se a conexao TCP nao for usada 00223 // (para transferir dados) durante este timeout. 00224 time_t m_ConnectionTimeOut; 00225 // Fila que armazena os dados pendendes a serem enviados por este 00226 // socket. 00227 TSendQueue m_SendQueue; 00228 // Variavel usada para indicar se estamos no processo de fechar a 00229 // conexao TCP. Neste caso, nao poderao ser inseridos mais dados na 00230 // fila do socket. 00231 bool m_isClosingSocket; 00232 #ifdef RIO_DEBUG2 00233 // Quantidade de pacotes recebidos 00234 unsigned int m_ReceiveCount; 00235 // Quantidade de pacotes enviados 00236 unsigned int m_SendCount; 00237 #endif 00238 // Identificador da thread responsavel por receber os dados pela conexao 00239 // TCP. 00240 pthread_t m_TcpNetMgrThreadId; 00241 // Mutex para garantir o acesso exclusivo aos dados do objeto da classe 00242 // compartilhados por quem usa o objeto, e para podermos usar a variavel 00243 // de condicao dada a seguir. 00244 pthread_mutex_t m_Mutex; 00245 // Variavel de condicao usada para bloquear a thread de recebimento de 00246 // dados ate que a conexao TCP seja estabelecida com sucesso. 00247 pthread_cond_t m_Cond; 00248 // Indica se devemos abortar a thread para poder finalizar o objeto. 00249 bool m_isAborted; 00250 // Indica se um sinal foi enviado para desbloquear a thread. 00251 bool m_SentSignal; 00252 // Socket UDP usado para desbloquear o poll quando precisamos enviar 00253 // dados pela primeira vez. 00254 int m_PollSocket; 00255 // Armazena o endereco do socket usado para desbloquear o poll. 00256 struct sockaddr_in m_PollSocketAddr; 00257 00258 /** 00259 * Funcao para obter um conjunto de dados a serem enviados do objeto 00260 * da classe. 00261 * @param Data ponteiro para armazenar o endereco do inicio dos dados 00262 * @param DataSize ponteiro para armazenar o tamanho dos dados a serem 00263 * transferidos. 00264 * @param Param ponteiro para armazenar o parametro void* (passado ao 00265 * chamarmos a funcao SendData da classe CNetTCP). 00266 * @return S_OK se nenhum erro ocorreu ou o erro em caso contrario. 00267 */ 00268 00269 RioResult GetSendData( char **Data, unsigned int *DataSize, 00270 void **Param ); 00271 00272 /** 00273 * Funcao para receber dados de uma conexao TCP associada ao stream. 00274 * @param Data ponteiro que ira armazenar o ponteiro em que os dados 00275 * foram armazenados 00276 * @param DataSize ponteiro para armazenar o tamanho dos dados lidos. 00277 * @result S_OK se nenhum erro ocorreu ao recebermos os dados, ou um 00278 * valor diferente de S_OK caso algum erro tenha ocorrido. 00279 */ 00280 RioResult ReceiveStreamData( char **Data, unsigned int *DataSize ); 00281 00282 /** 00283 * Funcao para enviar o primeiro bloco de dados pendente em um stream 00284 * TCP. 00285 * @param DataSize ponteiro para um parametro que armazenara o tamanho 00286 * dos dados enviados. 00287 * @param Param ponteiro para o parametro passado quando os dados forem 00288 * enviados pela funcao SendData. 00289 * @result S_OK se nenhum erro ocorreu ao enviarmos os dados, ou um 00290 * valor diferente de S_OK caso algum erro tenha ocorrido. 00291 */ 00292 RioResult SendStreamData( unsigned int *DataSize, void **Param ); 00293 00294 /** 00295 * Funcao para esperar ate que a funcao EnableConnection. 00296 * @return true se a conexao foi cancelada, ou false caso a conexao nao 00297 * tenha sido cancelada. 00298 */ 00299 bool WaitEnableConnection( void ); 00300 00301 /** 00302 * Funcao que efetivamente executa o codigo da thread de gerenciamento 00303 * da reda, chamada pela funcao ReceiveThreadEp (esta funcao e usada 00304 * para facilitar o acesso aos campos do objeto). 00305 * @return true se podemos deletar o objeto e false em caso contrario 00306 * (este valor e usado pela funcao TcpNetMgrThreadEp, que chama esta 00307 * funcao, para saber se o objeto passado em ThreadParam pode ou nao 00308 * ser removido. 00309 */ 00310 bool TcpNetMgrThread( void ); 00311 00312 /** 00313 * Funcao que trata da execucao do codigo da thread de gerenciamento das 00314 * conexoes TCP ativas. 00315 * @param ThreadParam ponteiro com o parametro da thread. Para esta 00316 * thread, e um ponteiro para um objeto da classe CNetTcp. 00317 */ 00318 static void *TcpNetMgrThreadEp( void *ThreadParam ); 00319 00320 public: 00321 /** 00322 * Construtor da classe, usado para criar um novo objeto. 00323 * @param NetTcp ponteiro para o objeto da classe CNetTcp que criou a 00324 * conexao TCP. 00325 * @param ServerInstance se a conexao esta associada a um cliente ou a 00326 * um servidor 00327 */ 00328 CTcpConnection( CNetTcp *NetTcp, bool ServerInstance ); 00329 00330 /** 00331 * Destrutor da classe, usado para remover um objeto criado. 00332 */ 00333 ~CTcpConnection(); 00334 00335 /** 00336 * Funcao para inicializar a nova conexao TCP criada. 00337 * @param IP endereco IP associado ao stream. 00338 * @param Port porta associadao ao stream. 00339 * @param Socket socket associado ao stream. 00340 * @param HostIP associado a maquina na qual o objeto foi alocado (usado 00341 * para criar o socket UDP). 00342 * @param ConnectionTimeOut tempo de timeout da conexao TCP. 00343 * @param LogRotation ponteiro para a classe que gerencia os logs. 00344 * @return S_OK se nenhum erro ocorreu ou o erro em caso contrario. 00345 */ 00346 RioResult Initialize( int IP, int Port, int Socket, int HostIP, 00347 time_t ConnectionTimeOut, 00348 CLogRotation *LogRotation ); 00349 00350 /** 00351 * Funcao para habilitar o uso da conexao TCP (a thread criada na funcao 00352 * Initialize acima ficara bloqueada em uma variavel de condicao ate 00353 * esta funcao ser chamada. 00354 * Obs: Esta funcao e usada para evitar que a thread da conexao execute 00355 * o select antes do processo de inicializacao da conexao ter sido 00356 * finalizado, o que poderia confundir este processo porque o select 00357 * poderia incorretamente reportar os dados de inicializacao como dados 00358 * validos recebidos (ou enviados) do (para o) outro lado. 00359 * @return S_OK se nenhum erro ocorreu ou o erro em caso contrario. 00360 */ 00361 RioResult EnableConnection( void ); 00362 00363 /** 00364 * Funcao para abortar a execucao da thread (a thread nao deletara o 00365 * objeto neste caso). A funcao esperara ate que a thread termine a sua 00366 * execucao. 00367 * @return S_OK se nenhum erro ocorreu ou o erro em caso contrario. 00368 */ 00369 RioResult CancelConnection( void ); 00370 00371 /** 00372 * Funcao para inserir um conjunto de dados a serem enviados 00373 * posteriormente pelo socket da conexao TCP. 00374 * @param Data ponteiro para o endereco do inicio dos dados a serem 00375 * enviados. 00376 * @param DataSize tamanho dos dados a serem enviados (em bytes). 00377 * @param Param parametro a ser passado quando os dados forem enviados 00378 * (passado ao chamarmos a funcao SendData da classe CNetTCP). 00379 * @param SendDataSize ponteiro para armazenar o tamanho atual da fila. 00380 * Se o tamanho for 1, precisaremos desbloquear o select. 00381 * @return S_OK se nenhum erro ocorreu ou o erro em caso contrario. 00382 */ 00383 00384 RioResult PutSendData( char *Data, unsigned int DataSize, void *Param, 00385 unsigned int *SendDataSize ); 00386 00387 /** 00388 * Funcao para obter o IP, a porta associado a conexao TCP do objeto 00389 * (usado para colocar o objeto na hash de conexoes). 00390 * @param IP ponteiro para o endreco onde colocaremos o IP. 00391 * @param Port ponteiro para o endereco onde colocaremos a porta. 00392 * @return S_OK se nenhum erro ocorreu ao obtermos o par IP, porta ou 00393 * diferente de S_OK se algum erro ocorreu. 00394 */ 00395 RioResult GetIpAndPort( int *IP, int *Port ); 00396 }; 00397 00398 // Classe que usa o TCP para o envio de dados 00399 class CNetTcp 00400 { 00401 private: 00402 // Define se a classe foi (true) ou nao (false) inicializada. 00403 bool m_Started; 00404 // Ponteiro para o objeto da classe de gerenciamento associada a este 00405 // objeto de envio dos dados. 00406 CNetInterface *m_NetInterface; 00407 // Identificador da Thread responsavel pelo estabelecimento das conexoes 00408 // TCP (somente para o servidor e o storage). 00409 pthread_t m_TcpServerThreadId; 00410 // Define se a instancia da classe esta associada a um cliente (false) 00411 // ou a um servidor (true) 00412 bool m_ServerInstance; 00413 // Define se o servidor TCP inicializou ou nao. 00414 bool m_TcpServerStarted; 00415 // Define se as threads devem terminar a suas execucoes. 00416 bool m_CancelThreads; 00417 // Ponteiro para o objeto da classe de gerenciamento dos logs de envio 00418 // de dados (usado somente pelo servidor). 00419 CLogRotation *m_LogRotation; 00420 // Armazena o tempo de timeout (em milisegundos) ao esperar pelos dados 00421 // (depois de o select indicar que existem dados disponiveis). 00422 unsigned int m_ReceiveTimeOut; 00423 // Armazena o tempo de timeout (em milisegundos) para o envio dos dados 00424 // (ao enviar os dados). 00425 unsigned int m_SendTimeOut; 00426 // Armazena o tempo de timeout (em sehundos) de uma das conexoes TCP 00427 // principal. O timeout ocorrera somente se a conexao TCP nao for usada 00428 // (para transferir dados) durante este timeout. 00429 time_t m_ConnectionTimeOut; 00430 // Identificador do socket do servidor TCP. 00431 int m_TcpServerSocket; 00432 // Endereco IP associado ao objeto da classe. 00433 int m_IP; 00434 // Numero da porta TCP do servidor (usado somente pelo servidor). 00435 int m_TcpServerPort; 00436 // Vetor com os enderecos (IP, porta) dos servidores TCP ao qual o 00437 // cliente se conectou. 00438 struct sockaddr_in *m_ServerAddress; 00439 // Vetor com os enderecos IP do cliente nos servidores. 00440 int *m_ClientIPAddress; 00441 // Vetor com os as portas do cliente nos servidores em cada um dos IPs 00442 // no vetor m_ClientIPAddress 00443 int *m_ClientPorts; 00444 // Numero de servidores em m_ServerAddress e m_CliendAddress. 00445 unsigned int m_AddressSize; 00446 // Variavel de condicao usada para bloquear a funcao Start ate que a 00447 // thread servidora do TCP tenha sido corretamente inicializada, e para 00448 // bloquear a thread que chamou CloseAllConnections (a partir da funcao 00449 // Stop) ate que todas as conexoes ativas sejam fechadas. 00450 pthread_cond_t m_Cond; 00451 // Mutex usado pela variavel de condicao m_Cond para esperar 00452 // pelo inicio do servidor TCP, na funcao Stop, para esperar a thread 00453 // do servidor estar no accept para podermos cancelar-la com seguranca, 00454 // para esperar, na funcao CloseAllConnections, todas as conexoes ativas 00455 // serem fechadas e para acessar a hash com as conexoes ativas. 00456 pthread_mutex_t m_Mutex; 00457 // Hash com as conexoes TCP ativas. A hash e enderecada pelo par 00458 // IP, porta associado a conexao. 00459 TTcpConnectionsMap m_TcpConnectionsMap; 00460 00461 /** 00462 * Funcao para retornar a chave do mapa associada a um dado par 00463 * IP,porta. 00464 * @param IP endereco IP associado a conexao TCP. 00465 * @param Port porta associada a conexao TCP. 00466 * @param Key string para armazenar a chave (supomos que a string tem 00467 * espaco suficiente para armazenar a string iii.iii.iii.iii.ppppp mais 00468 * o terminador '\0' (22 bytes). A constante 00469 */ 00470 void GetKey( int IP, int Port, char *Key ); 00471 00472 /** 00473 * Funcao para criar um novo objeto para uma nova conexao TCP. 00474 * @param IP endereco IP associado a conexao TCP. 00475 * @param Port porta associada a conexao TCP. 00476 * @param Socket socket associado a conexao TCP. 00477 * @param TcpConnetion ponteiro para um ponteiro para um objeto do 00478 * tipo CTcpConnection, que armazenara o ponteiro para o objeto deste 00479 * tipo criado para a nova conexao TCP. 00480 */ 00481 RioResult NewConnection( int IP, int Port, int Socket, 00482 CTcpConnection **TcpConnection ); 00483 00484 /** 00485 * Funcao para habilitar o uso da conexao TCP passada como parametro. 00486 * A funcao colocara o objeto na fila de objetos, e depois chamara a 00487 * funcao EnableConnection do objeto da conexao TCP passado como 00488 * parametro. 00489 * @param TcpConnection ponteiro para o objeto associado a conexao a ser 00490 * habilitada. 00491 * @return S_OK se nenhum erro ocorreu ao habilitar a conexao ou o 00492 * codigo do erro se algum erro ocorreu. 00493 */ 00494 RioResult EnableConnection( CTcpConnection *TcpConnection ); 00495 00496 /** 00497 * Funcao executada, pelo servidor, para inicializar e, se nao ocorrer 00498 * um erro, aceitar definitivamente uma conexao TCP criada com o 00499 * cliente 00500 * @param ClientSocket socket criado para o cliente pela chamada ao 00501 * sistema accept. 00502 * @param ClientIP IP da conexao TCP com o cliente. 00503 * @param ClientPort porta da conexao TCP com o cliente. 00504 * @return NULL se ocorreu algum erro ao gerarmos as conexoes, ou o 00505 * ponteiro para o objeto associado a nova conexao. 00506 */ 00507 CTcpConnection *TcpAccept( int ClientSocket, int ClientIP, 00508 int ClientPort ); 00509 00510 /** 00511 * Funcao para estabelecer uma conexao TCP com um dos servidores. 00512 * @param ServerIP endereco IP da conexao TCP no servidor. 00513 * @param ServerPort porta da conexao TCP no servidor. 00514 * @param ClientIP ponteiro para armazenar o IP associado ao cliente 00515 * (criada pela conexao). 00516 * @param ClientPort ponteiro para armazenar a porta associada ao 00517 * cliente (tambem criada pela conexao). 00518 * @return NULL se ocorreu algum erro ao gerarmos as conexoes, ou o 00519 * ponteiro para o objeto associado a nova conexao. 00520 */ 00521 CTcpConnection *TcpConnect( int ServerIP, int ServerPort, int *ClientIP, 00522 int *ClientPort ); 00523 00524 /** 00525 * Funcao que efetivamente executa o codigo da thread servidora do TCP, 00526 * chamada pela funcao TcpServerThreadEp (esta funcao e usada para 00527 * facilitar o acesso aos campos do objeto). 00528 */ 00529 void TcpServerThread( void ); 00530 /** 00531 * Funcao que trata da execucao do codigo da thread servidora do TCP 00532 * (somente para os servidores). 00533 * @param ThreadParam ponteiro com o parametro da thread. Para esta 00534 * thread, e um ponteiro para um objeto da classe CNetTcp. 00535 */ 00536 static void *TcpServerThreadEp( void *ThreadParam ); 00537 00538 /** 00539 * Funcao para fechar todas as conexoes TCP ativas, enviando ao outro 00540 * lado da conexao uma mensagem de que a conexao foi finalizada. 00541 * @return S_OK se nenhum erro ocorreu ao finalizar as conexoes, ou o 00542 * codigo de erro indicando o erro que ocorreu. 00543 */ 00544 RioResult CloseAllConnections(); 00545 00546 /** 00547 * Funcao para enviar dados para a maquina identificada nos parametros. 00548 * Obs: Note que os pacotes recebidos serao repassados ao objeto da 00549 * classe CNetInterface, usando a sua funcao ProcessData. 00550 * Obs2: Esta funcao nao verifica se a classe esta inicializada (para 00551 * fazer isso, usar a funcao SendData a seguir, que faz a verificacao e 00552 * depois chama esta funcao. 00553 * @param TcpConnection ponteiro para o objeto responsavel pela conexao 00554 * TCP. 00555 * @param Data ponteiro para o endereco inicial da memoria onde estao 00556 * armazenados os dados a serem enviados. 00557 * @param DataSize tamanho em bytes dos dados. 00558 * @param Param parametro a ser passado quando os dados forem enviados 00559 * e a funcao SendDataCompleted do objeto da classe CNetInterface for 00560 * chamado. 00561 * @result S_OK se nenhum erro ocorreu ao enviarmos os dados, ou um 00562 * valor diferente de S_OK caso algum erro tenha ocorrido. 00563 */ 00564 RioResult SendDataPrivate( CTcpConnection *TcpConnection, char *Data, 00565 unsigned int DataSize, void *Param ); 00566 00567 00568 public: 00569 #ifdef RIO_DEBUG_FILE 00570 // Log espeficico da classe (separado do RioErr). 00571 ofstream m_log; 00572 #endif 00573 00574 /** 00575 * Construtor da classe, usado para criar um novo objeto da classe. 00576 * @param NetInterface ponteiro para o objeto da classe CNetInterface 00577 * responsavel pelo gerenciamento deste objeto. 00578 */ 00579 CNetTcp( CNetInterface *NetInterface ); 00580 /** 00581 * Destrutor da classe, usado para deletar um objeto criado 00582 * anteriormente. 00583 */ 00584 ~CNetTcp(); 00585 /** 00586 * Funcao para inicializar a classe. Esta funcao deve ser chamada antes 00587 * de a classe poder ser usada. 00588 * @param NetConfig estrutura com as configuracoes do objeto (veja as 00589 * estruturas acima). 00590 * @return S_OK se a classe foi inicializada com sucesso, ou o erro caso 00591 * a inicializacao tenha falhado. 00592 */ 00593 RioResult Start( SNetTcpConfig *NetConfig ); 00594 /** 00595 * Funcao para parar o funcionamento do object (isto e, fechar todas as 00596 * conexoes TCP e terminar todas as threads). 00597 * @return S_OK se o objeto foi finalizado com sucesso, ou o erro caso 00598 * tenho ocorrido algum erro ao finalizar o objeto. 00599 */ 00600 RioResult Stop(); 00601 /** 00602 * Funcao para enviar dados para a maquina identificada nos parametros. 00603 * Obs: Note que os pacotes recebidos serao repassados ao objeto da 00604 * classe CNetInterface, usando a sua funcao ProcessData. 00605 * @param IP endereco IP da maquina destino 00606 * @param Port porta nesta maquina destino 00607 * @param Data ponteiro para o endereco inicial da memoria onde estao 00608 * armazenados os dados a serem enviados. 00609 * @param DataSize tamanho em bytes dos dados. 00610 * @param Param parametro a ser passado quando os dados forem enviados 00611 * e a funcao SendDataCompleted do objeto da classe CNetInterface for 00612 * chamado. 00613 * @result S_OK se nenhum erro ocorreu ao enviarmos os dados, ou um 00614 * valor diferente de S_OK caso algum erro tenha ocorrido. 00615 */ 00616 RioResult SendData( int IP, int Port, char *Data, unsigned int DataSize, 00617 void *Param ); 00618 00619 /** 00620 * Funcao para retornar o par IP, Porta associada a uma conexao com o 00621 * servidor definido pelo parametro server. 00622 * @param IP ponteiro para armazenar o endereco IP associado ao servidor 00623 * server. Se IP for NULL, o IP nao sera armazenado. 00624 * @param Port ponteiro para armazenar a porta associado ao servidor 00625 * server. Se Port for NULL, a porta nao sera armazenada. 00626 * @param Server identificador do servidor (em geral, 0=dispatcher e 00627 * 1,2,...=storages). Este parametro nao precisa ser passado e, neste 00628 * caso, o seu valor default sera 0 (usar o dispatcher). se o objeto 00629 * da classe estiver associado ao servidor, este parametro sera 00630 * ignorado. 00631 * @result S_OK se nenhum erro ocorreu obtermos o par IP, Porta, ou um 00632 * valor diferente de S_OK caso algum erro tenha ocorrido. 00633 */ 00634 RioResult GetIPAndPort( int *IP = NULL, int *Port = NULL, 00635 unsigned int Server = 0 ); 00636 00637 /** 00638 * Funcao para retornar um ponteiro para o vetor interno que armazena os 00639 * IPs e as portas. Se for o cliente, retornaremos os ponteiros para os 00640 * vetores com os IPs e as portas do cliente nos servidores e se for o 00641 * servidor, retornaremos um ponteiro para m_TcpIP e para 00642 * m_TcpServerPort. 00643 * @param IPs ponteiro para armazenar o ponteiro para os endercos IPs. 00644 * @param Ports ponteiro para armazenar o ponteiro para as portas. 00645 * @result S_OK se nenhum erro ocorreu obtermos os enderecos, ou um 00646 * valor diferente de S_OK caso algum erro tenha ocorrido. 00647 */ 00648 RioResult GetAllIPsAndPorts( int **IPs, int **Ports ); 00649 00650 /** 00651 * Funcao para verificar se um dado par IP, Porta esta ou nao associado 00652 * a uma conexao do objeto desta classe. 00653 * @param IP IP a ser verificado. 00654 * @param Port Porta a ser verificada. 00655 * @param isFound ponteiro para um valor booleando que sera true se o 00656 * par IP, Porta esta associado a uma conexao, ou false em caso 00657 * contrario. 00658 * @result S_OK se nenhum erro ocorreu buscarmos o par IP, Port, ou um 00659 * valor diferente de S_OK caso algum erro tenha ocorrido. 00660 */ 00661 RioResult FindIPAndPort( int IP, int Port, bool *isFound ); 00662 00663 /** 00664 * Funcao para definir o objeto (do tipo CLogRotation) a ser usado para 00665 * armazenar as estatisticas de envio de pacotes. 00666 * @param LogRotation ponteiro para um objeto do tipo CLogRotation. 00667 */ 00668 void setLogRotation( CLogRotation *LogRotation ); 00669 00670 /** 00671 * Esta funcao e chamada pelo objeto de uma das classes de rede ao 00672 * receber dados pela rede. 00673 * @param IP endereco IP da maquina que enviou os dados. 00674 * @param Port porta a partir da qual o pacote foi enviado a partir da 00675 * maquina que enviou estes dados 00676 * @param Data Dados enviados. 00677 * @param DataSize Tamanho dos dados. 00678 * Obs: Um tamanho igual a 0 indicara que a conexao foi fechada pelo 00679 * outro lado. Neste caso, a funcao devera fazer as tarefas necessarias 00680 * para fechar a conexao associada aos dados. 00681 */ 00682 void ProcessData( int IP, int Port, char *Data, unsigned int DataSize ); 00683 00684 /** 00685 * Esta Funcao sera chamada pelo objeto de uma das classes de rede 00686 * quando os dados tiverem sido enviados para um endereco (com ou sem 00687 * sucesso). 00688 * @param IP endereco ip da maquina que enviou os dados. 00689 * @param Port porta a partir da qual o pacote foi enviado a partir da 00690 * maquina que enviou estes dados 00691 * @param Param parametro passado quando os dados foram enviados. No 00692 * nosso caso, ele e o identificador da transferencia usada para enviar 00693 * os dados. 00694 */ 00695 void SendDataCompleted( int IP, int Port, void *Param ); 00696 00697 /** 00698 * Esta funcao e chamada quando algum erro ocorrer com a transferencia 00699 * de dados. 00700 * @param IP endereco IP da maquina associada ao socket com o erro. 00701 * @param Port porta associada ao socket com erro 00702 * @param RioError erro que ocorreu na transferencia dos dados. 00703 * @param Msg Mensagem a ser impressa junto com o erro (usada para 00704 * sabermos onde o erro foi gerado) 00705 * @param ErrorType tipo do erro que foi gerado (se foi gerado por um 00706 * recebimento de dados, por um envio de dados, ou por um outro motivo). 00707 * @param Param parametro generico opcional passado a funcao. No nosso 00708 * caso, quando nao NULL, contem o identificador da transferencia 00709 * associada ao erro (isso somente e usado pelo envio dos dados, no 00710 * recebimento, e passado sempre NULLTRANSFERID). 00711 */ 00712 void ProcessError( int IP, int Port, RioResult RioError, 00713 const char *Msg, EErrorType ErrorType, void *Param ); 00714 00715 /** 00716 * Esta funcao e chamada pelo objeto de uma das classes de rede quando 00717 * a conexao com o par IP, port for fechada. 00718 * 00719 * Os motivos atuais, dados pelo tipo ClosedType, sao: 00720 * 00721 * CONNECTIONCLOSED: a conexao foi fechada pelo outro lado. 00722 * CONNECTIONTIMEOUT: a conexao foi fechada por timeout. 00723 * 00724 * @param IP endereco IP da maquina associada ao socket com o erro. 00725 * @param Port porta associada ao socket com erro 00726 * @param timeout se for true a conexao foi fechada por timeout e, se 00727 * for false, a conexao foi fechada pelo outro lado da conexao. 00728 */ 00729 void ConnectionClosed( int IP, int Port, EClosedType ClosedType ); 00730 }; 00731 00732 #endif // __NETTCP_H_