2
Copyright (C) 2008 Romain Moret at Grame
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or
7
(at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
#include "JackNetWinSocket.h"
24
//utility *********************************************************************************************************
25
SERVER_EXPORT int GetHostName ( char * name, int size )
27
if ( gethostname ( name, size ) == SOCKET_ERROR )
29
jack_error ( "Can't get 'hostname' : %s", strerror ( NET_ERROR_CODE ) );
30
strcpy ( name, "default" );
36
win_net_error_t NetErrorList[] =
39
E ( WSAEINTR, "Interrupted system call" ),
40
E ( WSAEBADF, "Bad file number" ),
41
E ( WSAEACCES, "Permission denied" ),
42
E ( WSAEFAULT, "Bad address" ),
43
E ( WSAEINVAL, "Invalid argument" ),
44
E ( WSAEMFILE, "Too many open sockets" ),
45
E ( WSAEWOULDBLOCK, "Operation would block" ),
46
E ( WSAEINPROGRESS, "Operation now in progress" ),
47
E ( WSAEALREADY, "Operation already in progress" ),
48
E ( WSAENOTSOCK, "Socket operation on non-socket" ),
49
E ( WSAEDESTADDRREQ, "Destination address required" ),
50
E ( WSAEMSGSIZE, "Message too long" ),
51
E ( WSAEPROTOTYPE, "Protocol wrong type for socket" ),
52
E ( WSAENOPROTOOPT, "Bad protocol option" ),
53
E ( WSAEPROTONOSUPPORT, "Protocol not supported" ),
54
E ( WSAESOCKTNOSUPPORT, "Socket type not supported" ),
55
E ( WSAEOPNOTSUPP, "Operation not supported on socket" ),
56
E ( WSAEPFNOSUPPORT, "Protocol family not supported" ),
57
E ( WSAEAFNOSUPPORT, "Address family not supported" ),
58
E ( WSAEADDRINUSE, "Address already in use" ),
59
E ( WSAEADDRNOTAVAIL, "Can't assign requested address" ),
60
E ( WSAENETDOWN, "Network is down" ),
61
E ( WSAENETUNREACH, "Network is unreachable" ),
62
E ( WSAENETRESET, "Net connection reset" ),
63
E ( WSAECONNABORTED, "Software caused connection abort" ),
64
E ( WSAECONNRESET, "Connection reset by peer" ),
65
E ( WSAENOBUFS, "No buffer space available" ),
66
E ( WSAEISCONN, "Socket is already connected" ),
67
E ( WSAENOTCONN, "Socket is not connected" ),
68
E ( WSAESHUTDOWN, "Can't send after socket shutdown" ),
69
E ( WSAETOOMANYREFS, "Too many references, can't splice" ),
70
E ( WSAETIMEDOUT, "Connection timed out" ),
71
E ( WSAECONNREFUSED, "Connection refused" ),
72
E ( WSAELOOP, "Too many levels of symbolic links" ),
73
E ( WSAENAMETOOLONG, "File name too long" ),
74
E ( WSAEHOSTDOWN, "Host is down" ),
75
E ( WSAEHOSTUNREACH, "No route to host" ),
76
E ( WSAENOTEMPTY, "Directory not empty" ),
77
E ( WSAEPROCLIM, "Too many processes" ),
78
E ( WSAEUSERS, "Too many users" ),
79
E ( WSAEDQUOT, "Disc quota exceeded" ),
80
E ( WSAESTALE, "Stale NFS file handle" ),
81
E ( WSAEREMOTE, "Too many levels of remote in path" ),
82
E ( WSASYSNOTREADY, "Network system is unavailable" ),
83
E ( WSAVERNOTSUPPORTED, "Winsock version out of range" ),
84
E ( WSANOTINITIALISED, "WSAStartup not yet called" ),
85
E ( WSAEDISCON, "Graceful shutdown in progress" ),
86
E ( WSAHOST_NOT_FOUND, "Host not found" ),
87
E ( WSANO_DATA, "No host data of that type was found" ),
91
SERVER_EXPORT const char* PrintError ( int error )
94
for ( i = 0; NetErrorList[i].code >= 0; ++i )
96
if ( error == NetErrorList[i].code )
97
return NetErrorList[i].msg;
99
return strerror ( error );
102
//construct/destruct***********************************************************************************************
103
JackNetWinSocket::JackNetWinSocket()
106
fSendAddr.sin_family = AF_INET;
107
fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
108
memset ( &fSendAddr.sin_zero, 0, 8 );
109
fRecvAddr.sin_family = AF_INET;
110
fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
111
memset ( &fRecvAddr.sin_zero, 0, 8 );
114
JackNetWinSocket::JackNetWinSocket ( const char* ip, int port )
118
fSendAddr.sin_family = AF_INET;
119
fSendAddr.sin_port = htons ( port );
120
fSendAddr.sin_addr.s_addr = inet_addr ( ip );
121
memset ( &fSendAddr.sin_zero, 0, 8 );
122
fRecvAddr.sin_family = AF_INET;
123
fRecvAddr.sin_port = htons ( port );
124
fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
125
memset ( &fRecvAddr.sin_zero, 0, 8 );
128
JackNetWinSocket::JackNetWinSocket ( const JackNetWinSocket& socket )
131
fPort = socket.fPort;
132
fSendAddr = socket.fSendAddr;
133
fRecvAddr = socket.fRecvAddr;
136
JackNetWinSocket::~JackNetWinSocket()
141
JackNetWinSocket& JackNetWinSocket::operator= ( const JackNetWinSocket& socket )
143
if ( this != &socket )
146
fPort = socket.fPort;
147
fSendAddr = socket.fSendAddr;
148
fRecvAddr = socket.fRecvAddr;
153
//socket***********************************************************************************************************
154
int JackNetWinSocket::NewSocket()
161
fSockfd = socket ( AF_INET, SOCK_DGRAM, 0 );
165
int JackNetWinSocket::Bind()
167
return bind ( fSockfd, reinterpret_cast<SOCKADDR*> ( &fRecvAddr ), sizeof ( SOCKADDR ) );
170
int JackNetWinSocket::BindWith ( const char* ip )
172
fRecvAddr.sin_addr.s_addr = inet_addr ( ip );
176
int JackNetWinSocket::BindWith ( int port )
178
fRecvAddr.sin_port = htons ( port );
182
int JackNetWinSocket::Connect()
184
return connect ( fSockfd, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), sizeof ( SOCKADDR ) );
187
int JackNetWinSocket::ConnectTo ( const char* ip )
189
fSendAddr.sin_addr.s_addr = inet_addr ( ip );
193
void JackNetWinSocket::Close()
196
closesocket ( fSockfd );
200
void JackNetWinSocket::Reset()
202
fSendAddr.sin_family = AF_INET;
203
fSendAddr.sin_port = htons ( fPort );
204
fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
205
memset ( &fSendAddr.sin_zero, 0, 8 );
206
fRecvAddr.sin_family = AF_INET;
207
fRecvAddr.sin_port = htons ( fPort );
208
fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
209
memset ( &fRecvAddr.sin_zero, 0, 8 );
212
bool JackNetWinSocket::IsSocket()
214
return ( fSockfd ) ? true : false;
217
//IP/PORT***********************************************************************************************************
218
void JackNetWinSocket::SetPort ( int port )
221
fSendAddr.sin_port = htons ( port );
222
fRecvAddr.sin_port = htons ( port );
225
int JackNetWinSocket::GetPort()
230
//address***********************************************************************************************************
231
int JackNetWinSocket::SetAddress ( const char* ip, int port )
233
fSendAddr.sin_addr.s_addr = inet_addr ( ip );
234
fSendAddr.sin_port = htons ( port );
238
char* JackNetWinSocket::GetSendIP()
240
return inet_ntoa ( fSendAddr.sin_addr );
243
char* JackNetWinSocket::GetRecvIP()
245
return inet_ntoa ( fRecvAddr.sin_addr );
248
//utility************************************************************************************************************
249
int JackNetWinSocket::GetName ( char* name )
251
return gethostname ( name, 255 );
254
int JackNetWinSocket::JoinMCastGroup ( const char* ip )
256
struct ip_mreq multicast_req;
257
multicast_req.imr_multiaddr.s_addr = inet_addr ( ip );
258
multicast_req.imr_interface.s_addr = htonl ( INADDR_ANY );
259
//12 is IP_ADD_MEMBERSHIP in winsock2 (differs from winsock1...)
260
return SetOption ( IPPROTO_IP, 12, &multicast_req, sizeof ( multicast_req ) );
263
//options************************************************************************************************************
264
int JackNetWinSocket::SetOption ( int level, int optname, const void* optval, SOCKLEN optlen )
266
return setsockopt ( fSockfd, level, optname, static_cast<const char*> ( optval ), optlen );
269
int JackNetWinSocket::GetOption ( int level, int optname, void* optval, SOCKLEN* optlen )
271
return getsockopt ( fSockfd, level, optname, static_cast<char*> ( optval ), optlen );
274
//tiemout************************************************************************************************************
275
int JackNetWinSocket::SetTimeOut ( int usec )
277
jack_log ( "JackNetWinSocket::SetTimeout %d usec", usec );
279
//negative timeout, or exceeding 10s, return
280
if ( ( usec < 0 ) || ( usec > 10000000 ) )
282
int time = usec / 1000;
283
return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &time, sizeof ( time ) );
286
//local loop*********************************************************************************************************
287
int JackNetWinSocket::SetLocalLoop()
291
see http://msdn.microsoft.com/en-us/library/aa916098.aspx
292
Default value is TRUE. When TRUE, data that is sent from the local interface to the multicast group to
293
which the socket is joined, including data sent from the same socket, will be echoed to its receive buffer.
296
return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof ( disable ) );
299
//network operations*************************************************************************************************
300
int JackNetWinSocket::SendTo ( const void* buffer, size_t nbytes, int flags )
302
return sendto ( fSockfd, reinterpret_cast<const char*> ( buffer ), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), sizeof ( SOCKADDR ) );
305
int JackNetWinSocket::SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip )
307
fSendAddr.sin_addr.s_addr = inet_addr ( ip );
308
return SendTo ( buffer, nbytes, flags );
311
int JackNetWinSocket::Send ( const void* buffer, size_t nbytes, int flags )
313
return send ( fSockfd, reinterpret_cast<const char*> ( buffer ), nbytes, flags );
316
int JackNetWinSocket::RecvFrom ( void* buffer, size_t nbytes, int flags )
318
SOCKLEN addr_len = sizeof ( SOCKADDR );
319
return recvfrom ( fSockfd, reinterpret_cast<char*> ( buffer ), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fRecvAddr ), &addr_len );
322
int JackNetWinSocket::Recv ( void* buffer, size_t nbytes, int flags )
324
return recv ( fSockfd, reinterpret_cast<char*> ( buffer ), nbytes, flags );
327
int JackNetWinSocket::CatchHost ( void* buffer, size_t nbytes, int flags )
329
SOCKLEN addr_len = sizeof ( SOCKADDR );
330
return recvfrom ( fSockfd, reinterpret_cast<char*> ( buffer ), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), &addr_len );
333
net_error_t JackNetWinSocket::GetError()
335
switch ( NET_ERROR_CODE )
343
case WSAECONNREFUSED:
344
return NET_CONN_ERROR;
346
return NET_CONN_ERROR;
348
return NET_CONN_ERROR;
349
case WSAECONNABORTED:
350
return NET_CONN_ERROR;
352
return NET_CONN_ERROR;
353
case WSAEHOSTUNREACH:
354
return NET_CONN_ERROR;