Jack2 1.9.6
|
00001 /* 00002 Copyright (C) 2004-2008 Grame 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as published by 00006 the Free Software Foundation; either version 2.1 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 00018 */ 00019 00020 00021 #include "JackNetWinSocket.h" 00022 00023 namespace Jack 00024 { 00025 //utility ********************************************************************************************************* 00026 SERVER_EXPORT int GetHostName ( char * name, int size ) 00027 { 00028 if ( gethostname ( name, size ) == SOCKET_ERROR ) 00029 { 00030 jack_error ( "Can't get 'hostname' : %s", strerror ( NET_ERROR_CODE ) ); 00031 strcpy ( name, "default" ); 00032 return -1; 00033 } 00034 return 0; 00035 } 00036 00037 win_net_error_t NetErrorList[] = 00038 { 00039 E ( 0, "No error" ), 00040 E ( WSAEINTR, "Interrupted system call" ), 00041 E ( WSAEBADF, "Bad file number" ), 00042 E ( WSAEACCES, "Permission denied" ), 00043 E ( WSAEFAULT, "Bad address" ), 00044 E ( WSAEINVAL, "Invalid argument" ), 00045 E ( WSAEMFILE, "Too many open sockets" ), 00046 E ( WSAEWOULDBLOCK, "Operation would block" ), 00047 E ( WSAEINPROGRESS, "Operation now in progress" ), 00048 E ( WSAEALREADY, "Operation already in progress" ), 00049 E ( WSAENOTSOCK, "Socket operation on non-socket" ), 00050 E ( WSAEDESTADDRREQ, "Destination address required" ), 00051 E ( WSAEMSGSIZE, "Message too long" ), 00052 E ( WSAEPROTOTYPE, "Protocol wrong type for socket" ), 00053 E ( WSAENOPROTOOPT, "Bad protocol option" ), 00054 E ( WSAEPROTONOSUPPORT, "Protocol not supported" ), 00055 E ( WSAESOCKTNOSUPPORT, "Socket type not supported" ), 00056 E ( WSAEOPNOTSUPP, "Operation not supported on socket" ), 00057 E ( WSAEPFNOSUPPORT, "Protocol family not supported" ), 00058 E ( WSAEAFNOSUPPORT, "Address family not supported" ), 00059 E ( WSAEADDRINUSE, "Address already in use" ), 00060 E ( WSAEADDRNOTAVAIL, "Can't assign requested address" ), 00061 E ( WSAENETDOWN, "Network is down" ), 00062 E ( WSAENETUNREACH, "Network is unreachable" ), 00063 E ( WSAENETRESET, "Net connection reset" ), 00064 E ( WSAECONNABORTED, "Software caused connection abort" ), 00065 E ( WSAECONNRESET, "Connection reset by peer" ), 00066 E ( WSAENOBUFS, "No buffer space available" ), 00067 E ( WSAEISCONN, "Socket is already connected" ), 00068 E ( WSAENOTCONN, "Socket is not connected" ), 00069 E ( WSAESHUTDOWN, "Can't send after socket shutdown" ), 00070 E ( WSAETOOMANYREFS, "Too many references, can't splice" ), 00071 E ( WSAETIMEDOUT, "Connection timed out" ), 00072 E ( WSAECONNREFUSED, "Connection refused" ), 00073 E ( WSAELOOP, "Too many levels of symbolic links" ), 00074 E ( WSAENAMETOOLONG, "File name too long" ), 00075 E ( WSAEHOSTDOWN, "Host is down" ), 00076 E ( WSAEHOSTUNREACH, "No route to host" ), 00077 E ( WSAENOTEMPTY, "Directory not empty" ), 00078 E ( WSAEPROCLIM, "Too many processes" ), 00079 E ( WSAEUSERS, "Too many users" ), 00080 E ( WSAEDQUOT, "Disc quota exceeded" ), 00081 E ( WSAESTALE, "Stale NFS file handle" ), 00082 E ( WSAEREMOTE, "Too many levels of remote in path" ), 00083 E ( WSASYSNOTREADY, "Network system is unavailable" ), 00084 E ( WSAVERNOTSUPPORTED, "Winsock version out of range" ), 00085 E ( WSANOTINITIALISED, "WSAStartup not yet called" ), 00086 E ( WSAEDISCON, "Graceful shutdown in progress" ), 00087 E ( WSAHOST_NOT_FOUND, "Host not found" ), 00088 E ( WSANO_DATA, "No host data of that type was found" ), 00089 { -1, NULL }, 00090 }; 00091 00092 SERVER_EXPORT const char* PrintError ( int error ) 00093 { 00094 int i; 00095 for ( i = 0; NetErrorList[i].code >= 0; ++i ) 00096 { 00097 if ( error == NetErrorList[i].code ) 00098 return NetErrorList[i].msg; 00099 } 00100 return strerror ( error ); 00101 } 00102 00103 //construct/destruct*********************************************************************************************** 00104 JackNetWinSocket::JackNetWinSocket() 00105 { 00106 fSockfd = 0; 00107 fSendAddr.sin_family = AF_INET; 00108 fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); 00109 memset ( &fSendAddr.sin_zero, 0, 8 ); 00110 fRecvAddr.sin_family = AF_INET; 00111 fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); 00112 memset ( &fRecvAddr.sin_zero, 0, 8 ); 00113 } 00114 00115 JackNetWinSocket::JackNetWinSocket ( const char* ip, int port ) 00116 { 00117 fSockfd = 0; 00118 fPort = port; 00119 fSendAddr.sin_family = AF_INET; 00120 fSendAddr.sin_port = htons ( port ); 00121 fSendAddr.sin_addr.s_addr = inet_addr ( ip ); 00122 memset ( &fSendAddr.sin_zero, 0, 8 ); 00123 fRecvAddr.sin_family = AF_INET; 00124 fRecvAddr.sin_port = htons ( port ); 00125 fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); 00126 memset ( &fRecvAddr.sin_zero, 0, 8 ); 00127 } 00128 00129 JackNetWinSocket::JackNetWinSocket ( const JackNetWinSocket& socket ) 00130 { 00131 fSockfd = 0; 00132 fPort = socket.fPort; 00133 fSendAddr = socket.fSendAddr; 00134 fRecvAddr = socket.fRecvAddr; 00135 } 00136 00137 JackNetWinSocket::~JackNetWinSocket() 00138 { 00139 Close(); 00140 } 00141 00142 JackNetWinSocket& JackNetWinSocket::operator= ( const JackNetWinSocket& socket ) 00143 { 00144 if ( this != &socket ) 00145 { 00146 fSockfd = 0; 00147 fPort = socket.fPort; 00148 fSendAddr = socket.fSendAddr; 00149 fRecvAddr = socket.fRecvAddr; 00150 } 00151 return *this; 00152 } 00153 00154 //socket*********************************************************************************************************** 00155 int JackNetWinSocket::NewSocket() 00156 { 00157 if ( fSockfd ) 00158 { 00159 Close(); 00160 Reset(); 00161 } 00162 fSockfd = socket ( AF_INET, SOCK_DGRAM, 0 ); 00163 return fSockfd; 00164 } 00165 00166 int JackNetWinSocket::Bind() 00167 { 00168 return bind ( fSockfd, reinterpret_cast<SOCKADDR*> ( &fRecvAddr ), sizeof ( SOCKADDR ) ); 00169 } 00170 00171 int JackNetWinSocket::BindWith ( const char* ip ) 00172 { 00173 fRecvAddr.sin_addr.s_addr = inet_addr ( ip ); 00174 return Bind(); 00175 } 00176 00177 int JackNetWinSocket::BindWith ( int port ) 00178 { 00179 fRecvAddr.sin_port = htons ( port ); 00180 return Bind(); 00181 } 00182 00183 int JackNetWinSocket::Connect() 00184 { 00185 return connect ( fSockfd, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), sizeof ( SOCKADDR ) ); 00186 } 00187 00188 int JackNetWinSocket::ConnectTo ( const char* ip ) 00189 { 00190 fSendAddr.sin_addr.s_addr = inet_addr ( ip ); 00191 return Connect(); 00192 } 00193 00194 void JackNetWinSocket::Close() 00195 { 00196 if ( fSockfd ) 00197 closesocket ( fSockfd ); 00198 fSockfd = 0; 00199 } 00200 00201 void JackNetWinSocket::Reset() 00202 { 00203 fSendAddr.sin_family = AF_INET; 00204 fSendAddr.sin_port = htons ( fPort ); 00205 fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); 00206 memset ( &fSendAddr.sin_zero, 0, 8 ); 00207 fRecvAddr.sin_family = AF_INET; 00208 fRecvAddr.sin_port = htons ( fPort ); 00209 fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); 00210 memset ( &fRecvAddr.sin_zero, 0, 8 ); 00211 } 00212 00213 bool JackNetWinSocket::IsSocket() 00214 { 00215 return ( fSockfd ) ? true : false; 00216 } 00217 00218 //IP/PORT*********************************************************************************************************** 00219 void JackNetWinSocket::SetPort ( int port ) 00220 { 00221 fPort = port; 00222 fSendAddr.sin_port = htons ( port ); 00223 fRecvAddr.sin_port = htons ( port ); 00224 } 00225 00226 int JackNetWinSocket::GetPort() 00227 { 00228 return fPort; 00229 } 00230 00231 //address*********************************************************************************************************** 00232 int JackNetWinSocket::SetAddress ( const char* ip, int port ) 00233 { 00234 fSendAddr.sin_addr.s_addr = inet_addr ( ip ); 00235 fSendAddr.sin_port = htons ( port ); 00236 return 0; 00237 } 00238 00239 char* JackNetWinSocket::GetSendIP() 00240 { 00241 return inet_ntoa ( fSendAddr.sin_addr ); 00242 } 00243 00244 char* JackNetWinSocket::GetRecvIP() 00245 { 00246 return inet_ntoa ( fRecvAddr.sin_addr ); 00247 } 00248 00249 //utility************************************************************************************************************ 00250 int JackNetWinSocket::GetName ( char* name ) 00251 { 00252 return gethostname ( name, 255 ); 00253 } 00254 00255 int JackNetWinSocket::JoinMCastGroup ( const char* ip ) 00256 { 00257 struct ip_mreq multicast_req; 00258 multicast_req.imr_multiaddr.s_addr = inet_addr ( ip ); 00259 multicast_req.imr_interface.s_addr = htonl ( INADDR_ANY ); 00260 //12 is IP_ADD_MEMBERSHIP in winsock2 (differs from winsock1...) 00261 return SetOption ( IPPROTO_IP, 12, &multicast_req, sizeof ( multicast_req ) ); 00262 } 00263 00264 //options************************************************************************************************************ 00265 int JackNetWinSocket::SetOption ( int level, int optname, const void* optval, SOCKLEN optlen ) 00266 { 00267 return setsockopt ( fSockfd, level, optname, static_cast<const char*> ( optval ), optlen ); 00268 } 00269 00270 int JackNetWinSocket::GetOption ( int level, int optname, void* optval, SOCKLEN* optlen ) 00271 { 00272 return getsockopt ( fSockfd, level, optname, static_cast<char*> ( optval ), optlen ); 00273 } 00274 00275 //tiemout************************************************************************************************************ 00276 int JackNetWinSocket::SetTimeOut ( int usec ) 00277 { 00278 jack_log ( "JackNetWinSocket::SetTimeout %d usec", usec ); 00279 00280 //negative timeout, or exceeding 10s, return 00281 if ( ( usec < 0 ) || ( usec > 10000000 ) ) 00282 return SOCKET_ERROR; 00283 int time = usec / 1000; 00284 return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &time, sizeof ( time ) ); 00285 } 00286 00287 //local loop********************************************************************************************************* 00288 int JackNetWinSocket::SetLocalLoop() 00289 { 00290 //char disable = 0; 00291 /* 00292 see http://msdn.microsoft.com/en-us/library/aa916098.aspx 00293 Default value is TRUE. When TRUE, data that is sent from the local interface to the multicast group to 00294 which the socket is joined, including data sent from the same socket, will be echoed to its receive buffer. 00295 */ 00296 char disable = 1; 00297 return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof ( disable ) ); 00298 } 00299 00300 //network operations************************************************************************************************* 00301 int JackNetWinSocket::SendTo ( const void* buffer, size_t nbytes, int flags ) 00302 { 00303 return sendto ( fSockfd, reinterpret_cast<const char*> ( buffer ), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), sizeof ( SOCKADDR ) ); 00304 } 00305 00306 int JackNetWinSocket::SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip ) 00307 { 00308 fSendAddr.sin_addr.s_addr = inet_addr ( ip ); 00309 return SendTo ( buffer, nbytes, flags ); 00310 } 00311 00312 int JackNetWinSocket::Send ( const void* buffer, size_t nbytes, int flags ) 00313 { 00314 return send ( fSockfd, reinterpret_cast<const char*> ( buffer ), nbytes, flags ); 00315 } 00316 00317 int JackNetWinSocket::RecvFrom ( void* buffer, size_t nbytes, int flags ) 00318 { 00319 SOCKLEN addr_len = sizeof ( SOCKADDR ); 00320 return recvfrom ( fSockfd, reinterpret_cast<char*> ( buffer ), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fRecvAddr ), &addr_len ); 00321 } 00322 00323 int JackNetWinSocket::Recv ( void* buffer, size_t nbytes, int flags ) 00324 { 00325 return recv ( fSockfd, reinterpret_cast<char*> ( buffer ), nbytes, flags ); 00326 } 00327 00328 int JackNetWinSocket::CatchHost ( void* buffer, size_t nbytes, int flags ) 00329 { 00330 SOCKLEN addr_len = sizeof ( SOCKADDR ); 00331 return recvfrom ( fSockfd, reinterpret_cast<char*> ( buffer ), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), &addr_len ); 00332 } 00333 00334 net_error_t JackNetWinSocket::GetError() 00335 { 00336 switch ( NET_ERROR_CODE ) 00337 { 00338 case WSABASEERR: 00339 return NET_NO_ERROR; 00340 case WSAETIMEDOUT: 00341 return NET_NO_DATA; 00342 case WSAEWOULDBLOCK: 00343 return NET_NO_DATA; 00344 case WSAECONNREFUSED: 00345 return NET_CONN_ERROR; 00346 case WSAECONNRESET: 00347 return NET_CONN_ERROR; 00348 case WSAEACCES: 00349 return NET_CONN_ERROR; 00350 case WSAECONNABORTED: 00351 return NET_CONN_ERROR; 00352 case WSAEHOSTDOWN: 00353 return NET_CONN_ERROR; 00354 case WSAEHOSTUNREACH: 00355 return NET_CONN_ERROR; 00356 default: 00357 return NET_OP_ERROR; 00358 } 00359 } 00360 } 00361