Changeset 7541 in orxonox.OLD for branches/network/src/lib
- Timestamp:
- May 5, 2006, 3:55:47 PM (19 years ago)
- Location:
- branches/network/src/lib/network
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/network/src/lib/network/tcp_server_socket.cc
r7540 r7541 14 14 */ 15 15 16 /* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module 17 For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput 18 */ 19 #define DEBUG_MODULE_NETWORK 20 16 21 #include "tcp_server_socket.h" 22 #include "tcp_socket.h" 17 23 24 25 /* header for debug output */ 26 #include "debug.h" 27 28 TcpServerSocket::TcpServerSocket( int port ) : ServerSocket( port ) 29 { 30 init(); 31 listen(port); 32 } 33 34 /** 35 * Default destructor 36 */ 37 TcpServerSocket::~TcpServerSocket( ) 38 { 39 /* Quit SDL_net */ 40 // NOTE: what if other instances of NetworkSocket running? 41 SDLNet_Quit(); 42 PRINTF(5)("SDL_net shutdown\n"); 43 44 _isListening = false; 45 } 46 47 void TcpServerSocket::init( ) 48 { 49 /* set the class id for the base object */ 50 this->setClassID(CL_SERVER_SOCKET, "TcpServerSocket"); 51 52 terminateThread = false; 53 listenSocket = NULL; 54 _isListening = false; 55 56 if(SDLNet_Init()==-1) 57 { 58 PRINTF(1)("SDLNet_Init: %s\n", SDLNet_GetError()); 59 return; 60 } 61 else 62 PRINTF(5)("SDL_net initialized\n"); 63 64 PRINTF(0)("TcpServerSocket created\n"); 65 } 18 66 19 67 20 68 /** 21 * constructor which listens on port 22 * @param port port 69 * Tells the NetworkSocket to listen on a specific port for incoming connections. 70 * NetworkSocket::writeBytes(...) will have no effect until there is a valuable connection. 71 * @param port 23 72 */ 24 TcpServerSocket::TcpServerSocket( int port ) : ServerSocket( port)73 bool TcpServerSocket::listen(unsigned int port) 25 74 { 75 PRINTF(0)("TcpServerSocket::listen()\n"); 76 _isListening = true; 77 //check if not already connected or listening 78 if (listenSocket) 79 { 80 PRINTF(1)("TcpServerSocket::listen: tcpSocket!=NULL! maybe you already called listen or did not call close()!\n"); 81 _isListening = false; 82 return false; 83 } 84 85 IPaddress ip; 86 87 if (SDLNet_ResolveHost(&ip, NULL, port)==-1) 88 { 89 PRINTF(1)("SDLNet_ResolveHost: %s\n", SDLNet_GetError()); 90 _isListening = false; 91 return false; 92 } 93 94 listenSocket = SDLNet_TCP_Open(&ip); 95 96 if (!listenSocket) 97 { 98 PRINTF(1)("SDLNet_TCP_Open: %s\n", SDLNet_GetError()); 99 _isListening = false; 100 return false; 101 } 102 103 return true; 26 104 } 27 105 28 TcpServerSocket::~TcpServerSocket( ) 106 107 NetworkSocket* TcpServerSocket::getNewSocket( ) 29 108 { 30 } 109 if ( !listenSocket ) 110 { 111 PRINTF(1)("listenSocket == NULL! Maybe you forgot to call listen()\n"); 112 close(); 113 return NULL; 114 } 31 115 32 bool TcpServerSocket::listen( unsigned int port ) 33 { 34 } 116 TCPsocket sock = SDLNet_TCP_Accept(listenSocket); 35 117 36 NetworkSocket * TcpServerSocket::getNewSocket( void ) 37 { 118 if ( !sock ) 119 { 120 return NULL; 121 } 122 else 123 { 124 return new TcpSocket(sock); 125 } 38 126 } 39 127 40 128 void TcpServerSocket::close( ) 41 129 { 130 if ( listenSocket ) 131 { 132 SDLNet_TCP_Close( listenSocket ); 133 listenSocket = NULL; 134 } 135 136 _isListening = false; 42 137 } -
branches/network/src/lib/network/tcp_server_socket.h
r7540 r7541 27 27 virtual NetworkSocket* getNewSocket( void ); 28 28 virtual void close(); 29 30 private: 31 TCPsocket listenSocket; 32 bool terminateThread; 33 34 bool _isListening; 35 36 void init(); 29 37 30 38 }; -
branches/network/src/lib/network/tcp_socket.cc
r7540 r7541 1 1 2 /* 2 3 orxonox - the future of 3D-vertical-scrollers … … 10 11 11 12 ### File Specific: 12 main-programmer: Christoph Renner 13 main-programmer: Christoph Renner, David Hasenfratz 13 14 co-programmer: 14 15 */ 15 16 17 18 19 /* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module 20 For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput 21 */ 22 #define DEBUG_MODULE_NETWORK 23 24 #include "converter.h" 25 26 /* include your own header */ 16 27 #include "tcp_socket.h" 17 28 18 /** 19 * constructor which connects to host 29 /* header for debug output */ 30 #include "debug.h" 31 32 /** 33 * Default constructor 34 */ 35 TcpSocket::TcpSocket() 36 { 37 this->init(); 38 } 39 40 /** 41 * Constructor to connect directly 20 42 */ 21 43 TcpSocket::TcpSocket( std::string host, int port ) 22 44 { 23 } 24 25 /** 26 * default constructor 27 */ 28 TcpSocket::TcpSocket( ) 29 { 30 } 31 32 /** 33 * default destructor 45 this->init(); 46 connectToServer( host, port); 47 } 48 49 50 TcpSocket::TcpSocket( TCPsocket sock ) 51 { 52 this->init(); 53 this->tcpSocket = sock; 54 55 readThread = SDL_CreateThread(thread_read, (void*)this); 56 writeThread = SDL_CreateThread(thread_write, (void*)this); 57 } 58 59 void TcpSocket::init() 60 { 61 /* set the class id for the base object */ 62 this->setClassID(CL_NETWORK_SOCKET, "TcpSocket"); 63 64 tcpSocket = NULL; 65 incomingBufferLength = 0; 66 outgoingBufferLength = 0; 67 68 readThread = NULL; 69 writeThread = NULL; 70 71 72 thread_write_running = false; 73 thread_read_running = false; 74 75 incomingBufferMutex = SDL_CreateMutex(); 76 outgoingBufferMutex = SDL_CreateMutex(); 77 78 79 socketMutex = SDL_CreateMutex(); 80 terminateThread = false; 81 82 /* Init SDL_net */ 83 //NOTE: do we need to call SDLNet_Init for all instances? 84 if(SDLNet_Init()==-1) 85 { 86 PRINTF(1)("SDLNet_Init: %s\n", SDLNet_GetError()); 87 return; 88 } 89 else 90 PRINTF(5)("SDL_net initialized\n"); 91 92 PRINTF(0)("TcpSocket created\n"); 93 94 } 95 96 97 98 /** 99 * Default destructor 100 * dont use this from outside: use destroy() instead!! 34 101 */ 35 102 TcpSocket::~TcpSocket( ) 36 103 { 37 } 38 39 /** 40 * read a packet sent by another NetworkSocket 41 * @param data data will be copied here 42 * @param maxLength readPacket will not read more than maxLength 43 * @return bytes read. on error less than zero 44 */ 104 this->terminateThread = true; 105 /* Quit SDL_net */ 106 // NOTE: what if other instances of TcpSocket running? 107 SDLNet_Quit(); 108 PRINTF(5)("SDL_net shutdown\n"); 109 110 SDL_DestroyMutex(incomingBufferMutex); 111 SDL_DestroyMutex(outgoingBufferMutex); 112 SDL_DestroyMutex(socketMutex); 113 SDL_DestroyMutex(threadTerminationMutex); 114 } 115 116 /** 117 * This function establishes a TCP/UDP connection to a given server (function argument). 118 * It is called by the NetworkStream. It creates a TCP/UDP socket for the connection. 119 * @param ip 120 */ 121 void TcpSocket::connectToServer( std::string host, int port) 122 { 123 IPaddress ip; 124 125 bOk = true; 126 127 if ( SDLNet_ResolveHost( &ip, host.c_str(), port ) != 0 ) 128 { 129 PRINTF(1)("could not resolve host %s\n", host.c_str() ); 130 bOk = false; 131 return; 132 } 133 134 //check if not already connected or listening 135 if (tcpSocket) 136 { 137 PRINTF(1)("TcpSocket::listen: tcpSocket!=NULL! maybe you already called listen or connectToServer or did not call disconnectServer()!"); 138 } 139 140 /* Connect to the host and port contained in ip using a TCP connection. */ 141 tcpSocket = SDLNet_TCP_Open(&ip); 142 if(!tcpSocket) 143 { 144 PRINTF(1)("SDLNet_TCP_Open: %s\n", SDLNet_GetError()); 145 return; 146 } 147 148 readThread = SDL_CreateThread(thread_read, (void*)this); 149 writeThread = SDL_CreateThread(thread_write, (void*)this); 150 } 151 152 153 /** 154 * DTears down a TCP/UDP connection. 155 */ 156 void TcpSocket::disconnectServer( ) 157 { 158 terminateThread = true; 159 /* Close the connection */ 160 161 SDL_mutexP(socketMutex); 162 SDLNet_TCP_Close(tcpSocket); 163 tcpSocket = NULL; 164 SDL_mutexV(socketMutex); 165 } 166 167 168 /** 169 * This function writes some bytes (data) to the network connection (if the connection is already 170 * estabilhed) otherwise it just does nothing (silently discarding the data). And writes some 171 * warnings 172 * @param data: pointer to the data to send 173 * @param length: n bytes to send 174 * @return the number successfully written bytes 175 */ 176 int TcpSocket::writeBytes(byte * data, int length) 177 { 178 PRINTF(5)("TcpSocket::writeBytes()\n"); 179 #ifdef _USE_OUTGOING_BUFFER 180 181 #define min(a,b) (a<b)?a:b 182 int nbytes = min(_OUTGOING_BUFFER_SIZE - outgoingBufferLength, length); 183 #undef min 184 185 if (!tcpSocket || data==NULL || nbytes<=0) 186 { 187 assert(_OUTGOING_BUFFER_SIZE - outgoingBufferLength > 0); 188 return 0; 189 } 190 191 SDL_mutexP(outgoingBufferMutex); 192 193 memcpy(outgoingBuffer + outgoingBufferLength, data, nbytes); 194 outgoingBufferLength += nbytes; 195 196 SDL_mutexV(outgoingBufferMutex); 197 198 199 return nbytes; 200 #else 201 SDL_mutexP(socketMutex); 202 203 if (!tcpSocket || data==NULL) 204 return 0; 205 206 int res = SDLNet_TCP_Send(tcpSocket, data, length); 207 208 SDL_mutexV(socketMutex); 209 210 if (res<length) 211 PRINTF(1)("SDLNet_TCP_Send: %s\n", SDLNet_GetError()); 212 213 return res; 214 #endif 215 } 216 217 /** 218 * Reads in the bytes from the network interface and passes it to the NetworkStream. 219 * This function must internaly be implemented/connected as a thread, since the read 220 * functions of many network libraries are blocking an would therefore block the whole 221 * program. 222 * From outside, the thread shouldn't be accessible at all. 223 * @param data: pointer to memory, big enough to store length bytes 224 * @param length: n bytes to read 225 * @return the number successfully read bytes. -1 on error. may be less than length! 226 */ 227 int TcpSocket::readBytes(byte * data, int length) 228 { 229 PRINTF(5)("TcpSocket::readBytes()\n"); 230 if (data==NULL) 231 return 0; 232 233 int nbytes = (length<incomingBufferLength) ? length : incomingBufferLength; 234 235 236 //printf("readBytes: nbytes = %d; length=%d; incomingBufferLength=%d\n", nbytes, length, incomingBufferLength); 237 238 // just in case ... 239 if (nbytes<0) 240 return -1; 241 242 if (nbytes==0) 243 return 0; 244 245 SDL_mutexP(incomingBufferMutex); 246 247 memcpy(data, incomingBuffer, nbytes); 248 249 //important: use memmove because the memory areas may overlap 250 memmove(incomingBuffer, incomingBuffer+nbytes, incomingBufferLength-nbytes); 251 incomingBufferLength -= nbytes; 252 253 SDL_mutexV(incomingBufferMutex); 254 255 return nbytes; 256 } 257 258 /** 259 * Reads in the bytes form the network interface and passes it to the NetworkStream. 260 * It only reads the bytes if there are enough bytes in our buffer. 261 * @param data: pointer to memory, big enough to store length bytes 262 * @param length: n bytes to read 263 * @return the number successfully read bytes. -1 on error. 0 if there are not enough bytes in our buffer. 264 */ 265 int TcpSocket::readBlock(byte * data, int length) 266 { 267 printf("TcpSocket: got %i bytes, NetworkStream requested %i bytes\n", this->incomingBufferLength, length); 268 if (incomingBufferLength >= length) 269 return readBytes(data, length); 270 else return 0; 271 } 272 273 274 /** 275 * used to create a thread to read from socket 276 * @param data: pointer to TcpSocket 277 */ 278 int TcpSocket::thread_read( void * data ) 279 { 280 int nbytesread = 0; 281 int nbytestoread = 0; 282 char buffer[_LOCAL_BUFFER_SIZE]; 283 TcpSocket * self = (TcpSocket*)data; 284 285 self->thread_read_running = true; 286 287 while (!self->terminateThread) 288 { 289 #define min(a,b) (a<b)?a:b 290 nbytestoread = min(_INCOMING_BUFFER_SIZE - self->incomingBufferLength, _LOCAL_BUFFER_SIZE); 291 #undef min 292 293 //if buffer is full 294 if (nbytestoread<=0 || !self->tcpSocket) 295 { 296 SDL_Delay(_MSECONDS_SLEEP_FULL_BUFFER); 297 continue; 298 } 299 300 nbytesread = SDLNet_TCP_Recv(self->tcpSocket, buffer, nbytestoread); 301 302 SDL_mutexP(self->incomingBufferMutex); 303 304 if (nbytesread<=0) 305 { 306 if (nbytesread<0) 307 printf("SDLNet_TCP_Recv: %s\n", SDLNet_GetError()); 308 309 SDL_mutexP(self->socketMutex); 310 311 SDLNet_TCP_Close(self->tcpSocket); 312 self->tcpSocket = NULL; 313 314 SDL_mutexV(self->socketMutex); 315 SDL_mutexV(self->incomingBufferMutex); 316 continue; 317 } 318 319 //printf("thread_read: nbytesread=%d\n", nbytesread); 320 321 memcpy(self->incomingBuffer+self->incomingBufferLength, buffer, nbytesread); 322 self->incomingBufferLength += nbytesread; 323 324 SDL_mutexV(self->incomingBufferMutex); 325 } 326 327 SDL_mutexP(self->threadTerminationMutex); 328 self->thread_read_running = false; 329 330 if ( !self->thread_write_running ) 331 { 332 //delete self; 333 SDL_mutexV(self->threadTerminationMutex); 334 } 335 else 336 { 337 SDL_mutexV(self->threadTerminationMutex); 338 } 339 340 341 #ifdef DONTEXITTHREADS 342 while ( true ) 343 { 344 SDL_Delay(1000); 345 } 346 #endif 347 348 PRINTF(0)("QUIT READ THREAD\n"); 349 350 return 0; 351 } 352 353 int TcpSocket::thread_write( void * data ) 354 { 355 int nbyteswrite = 0; 356 int nbytestowrite = 0; 357 char buffer[_LOCAL_BUFFER_SIZE]; 358 TcpSocket * self = (TcpSocket*)data; 359 360 self->thread_write_running = true; 361 362 while (!self->terminateThread) 363 { 364 #define min(a,b) (a<b)?a:b 365 nbytestowrite = min(self->outgoingBufferLength, _LOCAL_BUFFER_SIZE); 366 #undef min 367 368 // printf("thread_write nbytes=%d listening=%d\n", nbytestowrite, (int)self->_isListening); 369 370 //if buffer is full 371 if (nbytestowrite<=0 || !self->tcpSocket) 372 { 373 SDL_Delay(_MSECONDS_SLEEP_EMPTY_BUFFER); 374 continue; 375 } 376 377 SDL_mutexP(self->outgoingBufferMutex); 378 379 //printf("a\n"); 380 381 memcpy(buffer, self->outgoingBuffer, nbytestowrite); 382 self->outgoingBufferLength -= nbytestowrite; 383 memmove(self->outgoingBuffer, self->outgoingBuffer+nbytestowrite, self->outgoingBufferLength); 384 385 SDL_mutexV(self->outgoingBufferMutex); 386 387 nbyteswrite = SDLNet_TCP_Send(self->tcpSocket, buffer, nbytestowrite); 388 389 if (nbyteswrite<=0) 390 { 391 printf("SDLNet_TCP_Recv: %s\n", SDLNet_GetError()); 392 393 SDL_mutexP(self->socketMutex); 394 395 SDLNet_TCP_Close(self->tcpSocket); 396 self->tcpSocket = NULL; 397 398 SDL_mutexV(self->socketMutex); 399 continue; 400 } 401 402 } 403 404 SDL_mutexP(self->threadTerminationMutex); 405 self->thread_write_running = false; 406 407 if ( !self->thread_read_running ) 408 { 409 //delete self; 410 SDL_mutexV(self->threadTerminationMutex); 411 } 412 else 413 { 414 SDL_mutexV(self->threadTerminationMutex); 415 } 416 417 #ifdef DONTEXITTHREADS 418 while ( true ) 419 { 420 SDL_Delay(1000); 421 } 422 #endif 423 424 PRINTF(0)("QUIT WRITE THREAD\n"); 425 426 return 0; 427 428 } 429 430 bool TcpSocket::writePacket( byte * data, int length ) 431 { 432 PRINTF(5)("TcpSocket::writePacket() size=%d\n", length); 433 434 if ( length > 1024 ) 435 PRINTF(2)("WARNING SENDING BIG PACKET SIZE = %d\n", length); 436 437 byte blen[INTSIZE]; 438 439 Converter::intToByteArray( length, blen, INTSIZE ); 440 441 writeBytes(blen, INTSIZE); 442 writeBytes(data, length); 443 } 444 45 445 int TcpSocket::readPacket( byte * data, int maxLength ) 46 446 { 47 } 48 49 /** 50 * send packet to connected socket. will be recieved as whole packet 51 * @param data pointer to data to send 52 * @param length lengt of packet to send 53 * @return true on success 54 */ 55 bool TcpSocket::writePacket( byte * data, int length ) 56 { 57 } 58 59 /** 60 * disconnect from server 61 */ 62 void TcpSocket::disconnectServer( ) 63 { 64 } 65 66 /** 67 * connect to server on host with port port 68 * @param host hostname might be xxx.xxx.xxx.xxx or localhost ... 69 * @param port port to connect to 70 */ 71 void TcpSocket::connectToServer( std::string host, int port ) 72 { 73 } 74 447 PRINTF(5)("TcpSocket::readPacket()\n"); 448 if (incomingBufferLength<INTSIZE) 449 { 450 return 0; 451 } 452 453 int blen; 454 Converter::byteArrayToInt( incomingBuffer, &blen ); 455 456 if (blen>maxLength) 457 { 458 PRINTF(1)("Buffersize is too small (%d) for packet (%d).\n", maxLength, blen); 459 assert(false); 460 return 0; 461 } 462 463 if (blen>incomingBufferLength) 464 { 465 return 0; 466 } 467 468 byte t[INTSIZE]; 469 readBytes(t, INTSIZE); 470 int res = readBytes(data, blen); 471 472 if (res!=blen) 473 return -1; 474 else 475 return blen; 476 477 } 478 479 -
branches/network/src/lib/network/tcp_socket.h
r7540 r7541 8 8 #define _TCP_SOCKET 9 9 10 //TODO HACK else gdb will not work on server 11 #define DONTEXITTHREADS 12 13 //if you want to use outgoing buffer define _USE_OUTGOING_BUFFER 14 #define _USE_OUTGOING_BUFFER 15 16 #define _INCOMING_BUFFER_SIZE 2024000 17 #define _OUTGOING_BUFFER_SIZE 2024000 18 #define _LOCAL_BUFFER_SIZE 1024 19 //sleep if incoming buffer is full 20 #define _MSECONDS_SLEEP_FULL_BUFFER 10 21 //sleep if outgoing buffer is empty 22 #define _MSECONDS_SLEEP_EMPTY_BUFFER 10 23 24 25 /* contains memmove and memcpy */ 26 #include <string.h> 27 28 #ifdef HAVE_SDL_H 29 #include <SDL_thread.h> 30 #else 31 #include <SDL/SDL_thread.h> 32 #endif 10 33 /* include this file, it contains some default definitions */ 11 34 #include "netdefs.h" 12 35 13 36 14 /* include base_object.h since all classes are derived from this one */37 /* include network_socket.h since all classes are derived from this one */ 15 38 #include "network_socket.h" 16 39 … … 20 43 TcpSocket(); 21 44 TcpSocket( std::string host, int port ); 45 TcpSocket(TCPsocket sock); 22 46 virtual ~TcpSocket(); 23 47 … … 30 54 virtual int readPacket(byte * data, int maxLength); 31 55 56 private: 57 TCPsocket tcpSocket; 58 59 byte incomingBuffer[_INCOMING_BUFFER_SIZE]; 60 #ifdef _USE_OUTGOING_BUFFER 61 byte outgoingBuffer[_OUTGOING_BUFFER_SIZE]; 62 #endif 63 int incomingBufferLength; 64 #ifdef _USE_OUTGOING_BUFFER 65 int outgoingBufferLength; 66 #endif 67 68 SDL_mutex * incomingBufferMutex; 69 #ifdef _USE_OUTGOING_BUFFER 70 SDL_mutex * outgoingBufferMutex; 71 #endif 72 SDL_mutex * socketMutex; 73 bool terminateThread; 74 75 SDL_mutex* threadTerminationMutex; 76 static int thread_read(void * data); 77 bool thread_read_running; 78 bool thread_write_running; 79 80 SDL_Thread* readThread; 81 SDL_Thread* writeThread; 82 83 #ifdef _USE_OUTGOING_BUFFER 84 static int thread_write(void * data); 85 #endif 86 87 int writeBytes(byte * data, int length); 88 int readBytes(byte * data, int length); 89 int readBlock(byte * data, int length); 90 91 void init(); 32 92 33 93 }; -
branches/network/src/lib/network/udp_socket.cc
r7540 r7541 20 20 void UdpSocket::init( ) 21 21 { 22 //TODO setClassId 22 23 this->serverSocket = NULL; 23 24 this->socket = NULL;
Note: See TracChangeset
for help on using the changeset viewer.