Network.cpp
上传用户:jxpjxmjjw
上传日期:2009-12-07
资源大小:5877k
文件大小:4k
源码类别:

模拟服务器

开发平台:

Visual C++

  1. // Copyright (C) 2004 Team Python
  2. //  
  3. // This program is free software; you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation; either version 2 of the License, or
  6. // (at your option) any later version.
  7. // 
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. // GNU General Public License for more details.
  12. // 
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software 
  15. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  16. #include "Network.h"
  17. #include "Sockets.h"
  18. #include "Threads.h"
  19. /// Singleton
  20. createFileSingleton( Network );
  21. Network::~Network( ) {
  22. clear( );
  23. }
  24. void Network::clear( ) {
  25. m_loggingWorld = false;
  26. NetworkInterfaceSet::iterator iterNI;
  27. /// Network's going down, close all open sockets
  28. for( iterNI = mInterfaces.begin( ); iterNI != mInterfaces.end( ); ++iterNI )
  29. delete ( NetworkInterface * ) (*iterNI);
  30. mInterfaces.clear( );
  31. }
  32. void Network::disconnectAll( ) {
  33. for( NetworkInterfaceSet::iterator iterNI = mInterfaces.begin( ); iterNI != mInterfaces.end( ); ++iterNI )
  34. (*iterNI)->mConnected = false;
  35. }
  36. Network::Network( ) {
  37. Initialise( );
  38. }
  39. void Network::Initialise( ) {
  40. #if PLATFORM == PLATFORM_WIN32
  41. // Load Winsock 2.0
  42. WSADATA wsda;
  43. WSAStartup(MAKEWORD(2,0), &wsda);
  44. #else
  45. signal(SIGPIPE, SIG_IGN);
  46. #endif
  47. m_loggingWorld = true;
  48. }
  49. NetworkInterface * Network::createWorldListener( int port, void ( * callback ) ( NetworkInterface * ) ) {
  50. int opt = 1;
  51. /// Create the socket
  52. NetworkInterface * tempNI = new NetworkInterface( );
  53. tempNI->mSocketID = ( uint32 ) socket( AF_INET, SOCK_STREAM, 0 );
  54. // TODO: if( tempNI->mSocketID == SOCKET_ERROR ) // catch error with WSAGetLastError()
  55. /// Make blocking(I think that's how i need to do it :/)
  56. uint32 nonblockingstate = false;
  57. IOCTL_SOCKET( tempNI->mSocketID, IOCTL_NOBLOCK, &nonblockingstate );
  58. // Make socket accept multiple connections
  59. setsockopt(tempNI->mSocketID, SOL_SOCKET, SO_REUSEADDR,(char *)&opt, sizeof(opt));
  60. /// Set the address
  61. SOCKADDR_IN tempAddr;
  62. tempAddr.sin_family = AF_INET;
  63. tempAddr.sin_port = htons( port );
  64. tempAddr.sin_addr.s_addr = htonl( INADDR_ANY ); // Listen on any interface
  65. tempNI->internalAddress = new SOCKADDR_IN( tempAddr );
  66. /// TODO: handle error case of bind
  67. NAssertRP( bind( tempNI->mSocketID, (struct sockaddr *) tempNI->internalAddress, sizeof( SOCKADDR_IN ) ) );
  68. /// TODO: handle error case of listen
  69. NAssertRP( listen( tempNI->mSocketID, SOMAXCONN ) );
  70. /// Add this listening interface to our set
  71. mInterfaces.insert( tempNI );
  72. return tempNI;
  73. }
  74. void Network::removeNetworkInterface( NetworkInterface * net ) {
  75. delete *mInterfaces.find( net );
  76. mInterfaces.erase( net );
  77. }
  78. char * Network::getErrorName( uint32 code ) {
  79. //assert( false );
  80. switch( code ) {
  81. case SOCKERR(FAULT):
  82. return "[EFAULT] Bad address";
  83. case SOCKERR(INTR):
  84. return "[EINTR] Interrupted function call";
  85. case SOCKERR(MFILE):
  86. return "[EMFILE] Too many open files";
  87. case SOCKERR(CONNRESET):
  88. return "[ECONNRESET] Connection reset by peer";
  89. case SOCKERR(ACCES):
  90. return "[EACCES] Permission denied";
  91. case SOCKERR(WOULDBLOCK):
  92. return "[EWOULDBLOCK] Resource temporarily unavailable";
  93. case SOCKERR(INVAL):
  94. return "[EINVAL] Invalid argument";
  95. case SOCKERR(CONNABORTED):
  96. return "[ECONNABORTED] Software caused connection abort";
  97. case SOCKERR(SHUTDOWN):
  98. return "[ESHUTDOWN] Cannot send after socket shutdown.";
  99. case SOCKERR(ADDRINUSE):
  100. return "[EADDRINUSE] Address already in use.";
  101. #if PLATFORM != PLATFORM_WIN32
  102. case SOCKERR(PIPE):
  103. return "[EPIPE] Broken pipe.";
  104. #endif
  105. case SOCKERR(TIMEDOUT):
  106. return "[ETIMEDOUT] Connection timed out.";
  107. }
  108. char buf[256];
  109. sprintf( buf, "unknown: %i", code );
  110. #if PLATFORM != PLATFORM_WIN32
  111. perror( " unknown ");
  112. #endif
  113. Log::getSingleton( ).outString( buf );
  114. assert( false && "UNKNOWN ERROR CODE" );
  115. return "UNKNOWN ERROR";
  116. }