|
- /*
- Copyright (C) 2008 Romain Moret at Grame
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- */
-
- #include "JackNetWinSocket.h"
-
- namespace Jack
- {
- //utility *********************************************************************************************************
- EXPORT int GetHostName ( char * name, int size )
- {
- if ( gethostname ( name, size ) == SOCKET_ERROR )
- {
- jack_error ( "Can't get 'hostname' : %s", strerror ( NET_ERROR_CODE ) );
- strcpy ( name, "default" );
- return -1;
- }
- return 0;
- }
-
- struct { int code; char* msg; } NetErrorList[] =
- {
- E(0, "No error"),
- E(WSAEINTR, "Interrupted system call"),
- E(WSAEBADF, "Bad file number"),
- E(WSAEACCES, "Permission denied"),
- E(WSAEFAULT, "Bad address"),
- E(WSAEINVAL, "Invalid argument"),
- E(WSAEMFILE, "Too many open sockets"),
- E(WSAEWOULDBLOCK, "Operation would block"),
- E(WSAEINPROGRESS, "Operation now in progress"),
- E(WSAEALREADY, "Operation already in progress"),
- E(WSAENOTSOCK, "Socket operation on non-socket"),
- E(WSAEDESTADDRREQ, "Destination address required"),
- E(WSAEMSGSIZE, "Message too long"),
- E(WSAEPROTOTYPE, "Protocol wrong type for socket"),
- E(WSAENOPROTOOPT, "Bad protocol option"),
- E(WSAEPROTONOSUPPORT, "Protocol not supported"),
- E(WSAESOCKTNOSUPPORT, "Socket type not supported"),
- E(WSAEOPNOTSUPP, "Operation not supported on socket"),
- E(WSAEPFNOSUPPORT, "Protocol family not supported"),
- E(WSAEAFNOSUPPORT, "Address family not supported"),
- E(WSAEADDRINUSE, "Address already in use"),
- E(WSAEADDRNOTAVAIL, "Can't assign requested address"),
- E(WSAENETDOWN, "Network is down"),
- E(WSAENETUNREACH, "Network is unreachable"),
- E(WSAENETRESET, "Net connection reset"),
- E(WSAECONNABORTED, "Software caused connection abort"),
- E(WSAECONNRESET, "Connection reset by peer"),
- E(WSAENOBUFS, "No buffer space available"),
- E(WSAEISCONN, "Socket is already connected"),
- E(WSAENOTCONN, "Socket is not connected"),
- E(WSAESHUTDOWN, "Can't send after socket shutdown"),
- E(WSAETOOMANYREFS, "Too many references, can't splice"),
- E(WSAETIMEDOUT, "Connection timed out"),
- E(WSAECONNREFUSED, "Connection refused"),
- E(WSAELOOP, "Too many levels of symbolic links"),
- E(WSAENAMETOOLONG, "File name too long"),
- E(WSAEHOSTDOWN, "Host is down"),
- E(WSAEHOSTUNREACH, "No route to host"),
- E(WSAENOTEMPTY, "Directory not empty"),
- E(WSAEPROCLIM, "Too many processes"),
- E(WSAEUSERS, "Too many users"),
- E(WSAEDQUOT, "Disc quota exceeded"),
- E(WSAESTALE, "Stale NFS file handle"),
- E(WSAEREMOTE, "Too many levels of remote in path"),
- E(WSASYSNOTREADY, "Network system is unavailable"),
- E(WSAVERNOTSUPPORTED, "Winsock version out of range"),
- E(WSANOTINITIALISED, "WSAStartup not yet called"),
- E(WSAEDISCON, "Graceful shutdown in progress"),
- E(WSAHOST_NOT_FOUND, "Host not found"),
- E(WSANO_DATA, "No host data of that type was found"),
- { -1, NULL },
- };
-
- EXPORT const char* PrintError ( int error )
- {
- int i;
- for ( i = 0; NetErrorList[i].code >= 0; ++i)
- {
- if ( error == NetErrorList[i].code )
- return NetErrorList[i].msg;
- }
- return strerror ( error );
- }
-
- //construct/destruct***********************************************************************************************
- JackNetWinSocket::JackNetWinSocket()
- {
- fSockfd = 0;
- fSendAddr.sin_family = AF_INET;
- fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
- memset ( &fSendAddr.sin_zero, 0, 8 );
- fRecvAddr.sin_family = AF_INET;
- fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
- memset ( &fRecvAddr.sin_zero, 0, 8 );
- }
-
- JackNetWinSocket::JackNetWinSocket ( const char* ip, int port )
- {
- fSockfd = 0;
- fPort = port;
- fSendAddr.sin_family = AF_INET;
- fSendAddr.sin_port = htons ( port );
- fSendAddr.sin_addr.s_addr = inet_addr ( ip );
- memset ( &fSendAddr.sin_zero, 0, 8 );
- fRecvAddr.sin_family = AF_INET;
- fRecvAddr.sin_port = htons ( port );
- fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
- memset ( &fRecvAddr.sin_zero, 0, 8 );
- }
-
- JackNetWinSocket::~JackNetWinSocket()
- {
- Close();
- }
-
- //socket***********************************************************************************************************
- int JackNetWinSocket::NewSocket()
- {
- if ( fSockfd )
- {
- Close();
- Reset();
- }
- fSockfd = socket ( AF_INET, SOCK_DGRAM, 0 );
- return fSockfd;
- }
-
- int JackNetWinSocket::Bind()
- {
- return bind ( fSockfd, reinterpret_cast<SOCKADDR*> ( &fRecvAddr ), sizeof ( SOCKADDR ) );
- }
-
- int JackNetWinSocket::BindWith ( const char* ip )
- {
- fRecvAddr.sin_addr.s_addr = inet_addr ( ip );
- return Bind();
- }
-
- int JackNetWinSocket::BindWith ( int port )
- {
- fRecvAddr.sin_port = htons ( port );
- return Bind();
- }
-
- int JackNetWinSocket::Connect()
- {
- return connect ( fSockfd, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), sizeof ( SOCKADDR ) );
- }
-
- int JackNetWinSocket::ConnectTo ( const char* ip )
- {
- fSendAddr.sin_addr.s_addr = inet_addr ( ip );
- return Connect();
- }
-
- void JackNetWinSocket::Close()
- {
- if ( fSockfd )
- closesocket ( fSockfd );
- fSockfd = 0;
- }
-
- void JackNetWinSocket::Reset()
- {
- fSendAddr.sin_family = AF_INET;
- fSendAddr.sin_port = htons ( fPort );
- fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
- memset ( &fSendAddr.sin_zero, 0, 8 );
- fRecvAddr.sin_family = AF_INET;
- fRecvAddr.sin_port = htons ( fPort );
- fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
- memset ( &fRecvAddr.sin_zero, 0, 8 );
- }
-
- bool JackNetWinSocket::IsSocket()
- {
- return ( fSockfd ) ? true : false;
- }
-
- //IP/PORT***********************************************************************************************************
- void JackNetWinSocket::SetPort ( int port )
- {
- fPort = port;
- fSendAddr.sin_port = htons ( port );
- fRecvAddr.sin_port = htons ( port );
- }
-
- int JackNetWinSocket::GetPort()
- {
- return fPort;
- }
-
- //address***********************************************************************************************************
- int JackNetWinSocket::SetAddress ( const char* ip, int port )
- {
- fSendAddr.sin_addr.s_addr = inet_addr ( ip );
- fSendAddr.sin_port = htons ( port );
- return 0;
- }
-
- char* JackNetWinSocket::GetSendIP()
- {
- return inet_ntoa ( fSendAddr.sin_addr );
- }
-
- char* JackNetWinSocket::GetRecvIP()
- {
- return inet_ntoa ( fRecvAddr.sin_addr );
- }
-
- //utility************************************************************************************************************
- int JackNetWinSocket::GetName ( char* name )
- {
- return gethostname ( name, 255 );
- }
-
- int JackNetWinSocket::JoinMCastGroup ( const char* ip )
- {
- struct ip_mreq multicast_req;
- multicast_req.imr_multiaddr.s_addr = inet_addr ( ip );
- multicast_req.imr_interface.s_addr = htonl ( INADDR_ANY );
- //12 is IP_ADD_MEMBERSHIP in winsock2 (differs from winsock1...)
- return SetOption ( IPPROTO_IP, 12, &multicast_req, sizeof ( multicast_req ) );
- }
-
- void JackNetWinSocket::CopyParams ( JackNetWinSocket* socket )
- {
- fPort = socket->fPort;
- fSendAddr = socket->fSendAddr;
- fRecvAddr = socket->fRecvAddr;
- }
-
- //options************************************************************************************************************
- int JackNetWinSocket::SetOption ( int level, int optname, const void* optval, SOCKLEN optlen )
- {
- return setsockopt ( fSockfd, level, optname, static_cast<const char*>(optval), optlen );
- }
-
- int JackNetWinSocket::GetOption ( int level, int optname, void* optval, SOCKLEN* optlen )
- {
- return getsockopt ( fSockfd, level, optname, static_cast<char*>(optval), optlen );
- }
-
- //tiemout************************************************************************************************************
- int JackNetWinSocket::SetTimeOut ( int& msec )
- {
- //negative timeout, or exceeding 10s, return
- if ( ( msec < 0 ) || ( msec > 10000 ) )
- return -1;
- return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &msec, sizeof ( msec ) );
- }
-
- //local loop*********************************************************************************************************
- int JackNetWinSocket::SetLocalLoop()
- {
- char enable = 1;
- return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &enable, sizeof ( enable ) );
- }
-
- //network operations*************************************************************************************************
- int JackNetWinSocket::SendTo ( const void* buffer, size_t nbytes, int flags )
- {
- return sendto ( fSockfd, reinterpret_cast<const char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), sizeof ( SOCKADDR ) );
- }
-
- int JackNetWinSocket::SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip )
- {
- fSendAddr.sin_addr.s_addr = inet_addr ( ip );
- return SendTo ( buffer, nbytes, flags );
- }
-
- int JackNetWinSocket::Send ( const void* buffer, size_t nbytes, int flags )
- {
- return send ( fSockfd, reinterpret_cast<const char*>(buffer), nbytes, flags );
- }
-
- int JackNetWinSocket::RecvFrom ( void* buffer, size_t nbytes, int flags )
- {
- SOCKLEN addr_len = sizeof ( SOCKADDR );
- return recvfrom ( fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fRecvAddr ), &addr_len );
- }
-
- int JackNetWinSocket::Recv ( void* buffer, size_t nbytes, int flags )
- {
- return recv ( fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags );
- }
-
- int JackNetWinSocket::CatchHost ( void* buffer, size_t nbytes, int flags )
- {
- SOCKLEN addr_len = sizeof ( SOCKADDR );
- return recvfrom ( fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), &addr_len );
- }
-
- net_error_t JackNetWinSocket::GetError()
- {
- switch ( NET_ERROR_CODE )
- {
- case WSABASEERR:
- return NET_NO_ERROR;
- case WSAETIMEDOUT:
- return NET_NO_DATA;
- case WSAECONNREFUSED:
- return NET_CONN_ERROR;
- case WSAECONNRESET:
- return NET_CONN_ERROR;
- case WSAEACCES:
- return NET_CONN_ERROR;
- case WSAECONNABORTED:
- return NET_CONN_ERROR;
- case WSAEHOSTDOWN:
- return NET_CONN_ERROR;
- case WSAEHOSTUNREACH:
- return NET_CONN_ERROR;
- default:
- return NET_OP_ERROR;
- }
- }
- }
-
|