2 Copyright (C) 2004-2008 Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include "JackNetWinSocket.h"
25 //utility *********************************************************************************************************
26 SERVER_EXPORT
int GetHostName ( char * name
, int size
)
28 if ( gethostname ( name
, size
) == SOCKET_ERROR
)
30 jack_error ( "Can't get 'hostname' : %s", strerror ( NET_ERROR_CODE
) );
31 strcpy ( name
, "default" );
37 win_net_error_t NetErrorList
[] =
40 E ( WSAEINTR
, "Interrupted system call" ),
41 E ( WSAEBADF
, "Bad file number" ),
42 E ( WSAEACCES
, "Permission denied" ),
43 E ( WSAEFAULT
, "Bad address" ),
44 E ( WSAEINVAL
, "Invalid argument" ),
45 E ( WSAEMFILE
, "Too many open sockets" ),
46 E ( WSAEWOULDBLOCK
, "Operation would block" ),
47 E ( WSAEINPROGRESS
, "Operation now in progress" ),
48 E ( WSAEALREADY
, "Operation already in progress" ),
49 E ( WSAENOTSOCK
, "Socket operation on non-socket" ),
50 E ( WSAEDESTADDRREQ
, "Destination address required" ),
51 E ( WSAEMSGSIZE
, "Message too long" ),
52 E ( WSAEPROTOTYPE
, "Protocol wrong type for socket" ),
53 E ( WSAENOPROTOOPT
, "Bad protocol option" ),
54 E ( WSAEPROTONOSUPPORT
, "Protocol not supported" ),
55 E ( WSAESOCKTNOSUPPORT
, "Socket type not supported" ),
56 E ( WSAEOPNOTSUPP
, "Operation not supported on socket" ),
57 E ( WSAEPFNOSUPPORT
, "Protocol family not supported" ),
58 E ( WSAEAFNOSUPPORT
, "Address family not supported" ),
59 E ( WSAEADDRINUSE
, "Address already in use" ),
60 E ( WSAEADDRNOTAVAIL
, "Can't assign requested address" ),
61 E ( WSAENETDOWN
, "Network is down" ),
62 E ( WSAENETUNREACH
, "Network is unreachable" ),
63 E ( WSAENETRESET
, "Net connection reset" ),
64 E ( WSAECONNABORTED
, "Software caused connection abort" ),
65 E ( WSAECONNRESET
, "Connection reset by peer" ),
66 E ( WSAENOBUFS
, "No buffer space available" ),
67 E ( WSAEISCONN
, "Socket is already connected" ),
68 E ( WSAENOTCONN
, "Socket is not connected" ),
69 E ( WSAESHUTDOWN
, "Can't send after socket shutdown" ),
70 E ( WSAETOOMANYREFS
, "Too many references, can't splice" ),
71 E ( WSAETIMEDOUT
, "Connection timed out" ),
72 E ( WSAECONNREFUSED
, "Connection refused" ),
73 E ( WSAELOOP
, "Too many levels of symbolic links" ),
74 E ( WSAENAMETOOLONG
, "File name too long" ),
75 E ( WSAEHOSTDOWN
, "Host is down" ),
76 E ( WSAEHOSTUNREACH
, "No route to host" ),
77 E ( WSAENOTEMPTY
, "Directory not empty" ),
78 E ( WSAEPROCLIM
, "Too many processes" ),
79 E ( WSAEUSERS
, "Too many users" ),
80 E ( WSAEDQUOT
, "Disc quota exceeded" ),
81 E ( WSAESTALE
, "Stale NFS file handle" ),
82 E ( WSAEREMOTE
, "Too many levels of remote in path" ),
83 E ( WSASYSNOTREADY
, "Network system is unavailable" ),
84 E ( WSAVERNOTSUPPORTED
, "Winsock version out of range" ),
85 E ( WSANOTINITIALISED
, "WSAStartup not yet called" ),
86 E ( WSAEDISCON
, "Graceful shutdown in progress" ),
87 E ( WSAHOST_NOT_FOUND
, "Host not found" ),
88 E ( WSANO_DATA
, "No host data of that type was found" ),
92 SERVER_EXPORT
const char* PrintError ( int error
)
95 for ( i
= 0; NetErrorList
[i
].code
>= 0; ++i
)
97 if ( error
== NetErrorList
[i
].code
)
98 return NetErrorList
[i
].msg
;
100 return strerror ( error
);
103 //construct/destruct***********************************************************************************************
104 JackNetWinSocket::JackNetWinSocket()
107 fSendAddr
.sin_family
= AF_INET
;
108 fSendAddr
.sin_addr
.s_addr
= htonl ( INADDR_ANY
);
109 memset ( &fSendAddr
.sin_zero
, 0, 8 );
110 fRecvAddr
.sin_family
= AF_INET
;
111 fRecvAddr
.sin_addr
.s_addr
= htonl ( INADDR_ANY
);
112 memset ( &fRecvAddr
.sin_zero
, 0, 8 );
115 JackNetWinSocket::JackNetWinSocket ( const char* ip
, int port
)
119 fSendAddr
.sin_family
= AF_INET
;
120 fSendAddr
.sin_port
= htons ( port
);
121 fSendAddr
.sin_addr
.s_addr
= inet_addr ( ip
);
122 memset ( &fSendAddr
.sin_zero
, 0, 8 );
123 fRecvAddr
.sin_family
= AF_INET
;
124 fRecvAddr
.sin_port
= htons ( port
);
125 fRecvAddr
.sin_addr
.s_addr
= htonl ( INADDR_ANY
);
126 memset ( &fRecvAddr
.sin_zero
, 0, 8 );
129 JackNetWinSocket::JackNetWinSocket ( const JackNetWinSocket
& socket
)
132 fPort
= socket
.fPort
;
133 fSendAddr
= socket
.fSendAddr
;
134 fRecvAddr
= socket
.fRecvAddr
;
137 JackNetWinSocket::~JackNetWinSocket()
142 JackNetWinSocket
& JackNetWinSocket::operator= ( const JackNetWinSocket
& socket
)
144 if ( this != &socket
)
147 fPort
= socket
.fPort
;
148 fSendAddr
= socket
.fSendAddr
;
149 fRecvAddr
= socket
.fRecvAddr
;
154 //socket***********************************************************************************************************
155 int JackNetWinSocket::NewSocket()
162 fSockfd
= socket ( AF_INET
, SOCK_DGRAM
, 0 );
166 int JackNetWinSocket::Bind()
168 return bind ( fSockfd
, reinterpret_cast<SOCKADDR
*> ( &fRecvAddr
), sizeof ( SOCKADDR
) );
171 int JackNetWinSocket::BindWith ( const char* ip
)
173 fRecvAddr
.sin_addr
.s_addr
= inet_addr ( ip
);
177 int JackNetWinSocket::BindWith ( int port
)
179 fRecvAddr
.sin_port
= htons ( port
);
183 int JackNetWinSocket::Connect()
185 return connect ( fSockfd
, reinterpret_cast<SOCKADDR
*> ( &fSendAddr
), sizeof ( SOCKADDR
) );
188 int JackNetWinSocket::ConnectTo ( const char* ip
)
190 fSendAddr
.sin_addr
.s_addr
= inet_addr ( ip
);
194 void JackNetWinSocket::Close()
197 closesocket ( fSockfd
);
201 void JackNetWinSocket::Reset()
203 fSendAddr
.sin_family
= AF_INET
;
204 fSendAddr
.sin_port
= htons ( fPort
);
205 fSendAddr
.sin_addr
.s_addr
= htonl ( INADDR_ANY
);
206 memset ( &fSendAddr
.sin_zero
, 0, 8 );
207 fRecvAddr
.sin_family
= AF_INET
;
208 fRecvAddr
.sin_port
= htons ( fPort
);
209 fRecvAddr
.sin_addr
.s_addr
= htonl ( INADDR_ANY
);
210 memset ( &fRecvAddr
.sin_zero
, 0, 8 );
213 bool JackNetWinSocket::IsSocket()
215 return ( fSockfd
) ? true : false;
218 //IP/PORT***********************************************************************************************************
219 void JackNetWinSocket::SetPort ( int port
)
222 fSendAddr
.sin_port
= htons ( port
);
223 fRecvAddr
.sin_port
= htons ( port
);
226 int JackNetWinSocket::GetPort()
231 //address***********************************************************************************************************
232 int JackNetWinSocket::SetAddress ( const char* ip
, int port
)
234 fSendAddr
.sin_addr
.s_addr
= inet_addr ( ip
);
235 fSendAddr
.sin_port
= htons ( port
);
239 char* JackNetWinSocket::GetSendIP()
241 return inet_ntoa ( fSendAddr
.sin_addr
);
244 char* JackNetWinSocket::GetRecvIP()
246 return inet_ntoa ( fRecvAddr
.sin_addr
);
249 //utility************************************************************************************************************
250 int JackNetWinSocket::GetName ( char* name
)
252 return gethostname ( name
, 255 );
255 int JackNetWinSocket::JoinMCastGroup ( const char* ip
)
257 struct ip_mreq multicast_req
;
258 multicast_req
.imr_multiaddr
.s_addr
= inet_addr ( ip
);
259 multicast_req
.imr_interface
.s_addr
= htonl ( INADDR_ANY
);
260 //12 is IP_ADD_MEMBERSHIP in winsock2 (differs from winsock1...)
261 return SetOption ( IPPROTO_IP
, 12, &multicast_req
, sizeof ( multicast_req
) );
264 //options************************************************************************************************************
265 int JackNetWinSocket::SetOption ( int level
, int optname
, const void* optval
, SOCKLEN optlen
)
267 return setsockopt ( fSockfd
, level
, optname
, static_cast<const char*> ( optval
), optlen
);
270 int JackNetWinSocket::GetOption ( int level
, int optname
, void* optval
, SOCKLEN
* optlen
)
272 return getsockopt ( fSockfd
, level
, optname
, static_cast<char*> ( optval
), optlen
);
275 //tiemout************************************************************************************************************
276 int JackNetWinSocket::SetTimeOut ( int usec
)
278 jack_log ( "JackNetWinSocket::SetTimeout %d usec", usec
);
280 //negative timeout, or exceeding 10s, return
281 if ( ( usec
< 0 ) || ( usec
> 10000000 ) )
283 int time
= usec
/ 1000;
284 return SetOption ( SOL_SOCKET
, SO_RCVTIMEO
, &time
, sizeof ( time
) );
287 //local loop*********************************************************************************************************
288 int JackNetWinSocket::SetLocalLoop()
292 see http://msdn.microsoft.com/en-us/library/aa916098.aspx
293 Default value is TRUE. When TRUE, data that is sent from the local interface to the multicast group to
294 which the socket is joined, including data sent from the same socket, will be echoed to its receive buffer.
297 return SetOption ( IPPROTO_IP
, IP_MULTICAST_LOOP
, &disable
, sizeof ( disable
) );
300 //network operations*************************************************************************************************
301 int JackNetWinSocket::SendTo ( const void* buffer
, size_t nbytes
, int flags
)
303 return sendto ( fSockfd
, reinterpret_cast<const char*> ( buffer
), nbytes
, flags
, reinterpret_cast<SOCKADDR
*> ( &fSendAddr
), sizeof ( SOCKADDR
) );
306 int JackNetWinSocket::SendTo ( const void* buffer
, size_t nbytes
, int flags
, const char* ip
)
308 fSendAddr
.sin_addr
.s_addr
= inet_addr ( ip
);
309 return SendTo ( buffer
, nbytes
, flags
);
312 int JackNetWinSocket::Send ( const void* buffer
, size_t nbytes
, int flags
)
314 return send ( fSockfd
, reinterpret_cast<const char*> ( buffer
), nbytes
, flags
);
317 int JackNetWinSocket::RecvFrom ( void* buffer
, size_t nbytes
, int flags
)
319 SOCKLEN addr_len
= sizeof ( SOCKADDR
);
320 return recvfrom ( fSockfd
, reinterpret_cast<char*> ( buffer
), nbytes
, flags
, reinterpret_cast<SOCKADDR
*> ( &fRecvAddr
), &addr_len
);
323 int JackNetWinSocket::Recv ( void* buffer
, size_t nbytes
, int flags
)
325 return recv ( fSockfd
, reinterpret_cast<char*> ( buffer
), nbytes
, flags
);
328 int JackNetWinSocket::CatchHost ( void* buffer
, size_t nbytes
, int flags
)
330 SOCKLEN addr_len
= sizeof ( SOCKADDR
);
331 return recvfrom ( fSockfd
, reinterpret_cast<char*> ( buffer
), nbytes
, flags
, reinterpret_cast<SOCKADDR
*> ( &fSendAddr
), &addr_len
);
334 net_error_t
JackNetWinSocket::GetError()
336 switch ( NET_ERROR_CODE
)
344 case WSAECONNREFUSED
:
345 return NET_CONN_ERROR
;
347 return NET_CONN_ERROR
;
349 return NET_CONN_ERROR
;
350 case WSAECONNABORTED
:
351 return NET_CONN_ERROR
;
353 return NET_CONN_ERROR
;
354 case WSAEHOSTUNREACH
:
355 return NET_CONN_ERROR
;