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.
20 #include "JackError.h"
21 #include "JackNetWinSocket.h"
25 //utility *********************************************************************************************************
26 SERVER_EXPORT
int GetHostName(char * name
, int size
)
28 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
) {
95 if (error
== NetErrorList
[i
].code
)
96 return NetErrorList
[i
].msg
;
98 return strerror(error
);
101 //construct/destruct***********************************************************************************************
102 JackNetWinSocket::JackNetWinSocket()
105 fSendAddr
.sin_family
= AF_INET
;
106 fSendAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
107 memset(&fSendAddr
.sin_zero
, 0, 8);
108 fRecvAddr
.sin_family
= AF_INET
;
109 fRecvAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
110 memset(&fRecvAddr
.sin_zero
, 0, 8);
113 JackNetWinSocket::JackNetWinSocket(const char* ip
, int port
)
117 fSendAddr
.sin_family
= AF_INET
;
118 fSendAddr
.sin_port
= htons(port
);
119 fSendAddr
.sin_addr
.s_addr
= inet_addr(ip
);
120 memset(&fSendAddr
.sin_zero
, 0, 8);
121 fRecvAddr
.sin_family
= AF_INET
;
122 fRecvAddr
.sin_port
= htons(port
);
123 fRecvAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
124 memset(&fRecvAddr
.sin_zero
, 0, 8);
127 JackNetWinSocket::JackNetWinSocket(const JackNetWinSocket
& socket
)
130 fPort
= socket
.fPort
;
131 fSendAddr
= socket
.fSendAddr
;
132 fRecvAddr
= socket
.fRecvAddr
;
135 JackNetWinSocket::~JackNetWinSocket()
140 JackNetWinSocket
& JackNetWinSocket::operator=(const JackNetWinSocket
& socket
)
142 if (this != &socket
) {
144 fPort
= socket
.fPort
;
145 fSendAddr
= socket
.fSendAddr
;
146 fRecvAddr
= socket
.fRecvAddr
;
151 //socket***********************************************************************************************************
152 int JackNetWinSocket::NewSocket()
158 fSockfd
= socket(AF_INET
, SOCK_DGRAM
, 0);
162 bool JackNetWinSocket::IsLocal(char* ip
)
164 if (strcmp(ip
, "127.0.0.1") == 0) {
169 gethostname(host_name
, sizeof(host_name
));
171 struct hostent
* host
= gethostbyname(host_name
);
173 for (int i
= 0; host
->h_addr_list
[i
] != 0; ++i
) {
175 memcpy(&addr
, host
->h_addr_list
[i
], sizeof(struct in_addr
));
176 if (strcmp(inet_ntoa(addr
), ip
) == 0) {
186 int JackNetWinSocket::Bind()
188 return bind(fSockfd
, reinterpret_cast<SOCKADDR
*>(&fRecvAddr
), sizeof(SOCKADDR
));
191 int JackNetWinSocket::BindWith(const char* ip
)
193 fRecvAddr
.sin_addr
.s_addr
= inet_addr(ip
);
197 int JackNetWinSocket::BindWith(int port
)
199 fRecvAddr
.sin_port
= htons(port
);
203 int JackNetWinSocket::Connect()
205 return connect(fSockfd
, reinterpret_cast<SOCKADDR
*>(&fSendAddr
), sizeof(SOCKADDR
));
208 int JackNetWinSocket::ConnectTo(const char* ip
)
210 fSendAddr
.sin_addr
.s_addr
= inet_addr(ip
);
214 void JackNetWinSocket::Close()
217 closesocket(fSockfd
);
221 void JackNetWinSocket::Reset()
223 fSendAddr
.sin_family
= AF_INET
;
224 fSendAddr
.sin_port
= htons(fPort
);
225 fSendAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
226 memset(&fSendAddr
.sin_zero
, 0, 8);
227 fRecvAddr
.sin_family
= AF_INET
;
228 fRecvAddr
.sin_port
= htons(fPort
);
229 fRecvAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
230 memset(&fRecvAddr
.sin_zero
, 0, 8);
233 bool JackNetWinSocket::IsSocket()
235 return(fSockfd
) ? true : false;
238 //IP/PORT***********************************************************************************************************
239 void JackNetWinSocket::SetPort(int port
)
242 fSendAddr
.sin_port
= htons(port
);
243 fRecvAddr
.sin_port
= htons(port
);
246 int JackNetWinSocket::GetPort()
251 //address***********************************************************************************************************
252 int JackNetWinSocket::SetAddress(const char* ip
, int port
)
254 fSendAddr
.sin_addr
.s_addr
= inet_addr(ip
);
255 fSendAddr
.sin_port
= htons(port
);
259 char* JackNetWinSocket::GetSendIP()
261 return inet_ntoa(fSendAddr
.sin_addr
);
264 char* JackNetWinSocket::GetRecvIP()
266 return inet_ntoa(fRecvAddr
.sin_addr
);
269 //utility************************************************************************************************************
270 int JackNetWinSocket::GetName(char* name
)
272 return gethostname(name
, 255);
275 int JackNetWinSocket::JoinMCastGroup(const char* ip
)
277 struct ip_mreq multicast_req
;
278 multicast_req
.imr_multiaddr
.s_addr
= inet_addr(ip
);
279 multicast_req
.imr_interface
.s_addr
= htonl(INADDR_ANY
);
280 //12 is IP_ADD_MEMBERSHIP in winsock2 (differs from winsock1...)
281 return SetOption(IPPROTO_IP
, 12, &multicast_req
, sizeof(multicast_req
));
284 //options************************************************************************************************************
285 int JackNetWinSocket::SetOption(int level
, int optname
, const void* optval
, SOCKLEN optlen
)
287 return setsockopt(fSockfd
, level
, optname
, static_cast<const char*>(optval
), optlen
);
290 int JackNetWinSocket::GetOption(int level
, int optname
, void* optval
, SOCKLEN
* optlen
)
292 return getsockopt(fSockfd
, level
, optname
, static_cast<char*>(optval
), optlen
);
295 //timeout************************************************************************************************************
296 int JackNetWinSocket::SetTimeOut(int usec
)
298 jack_log("JackNetWinSocket::SetTimeout %d usec", usec
);
299 int millisec
= usec
/ 1000;
300 return SetOption(SOL_SOCKET
, SO_RCVTIMEO
, &millisec
, sizeof(millisec
));
303 //local loop*********************************************************************************************************
304 int JackNetWinSocket::SetLocalLoop()
308 see http://msdn.microsoft.com/en-us/library/aa916098.aspx
309 Default value is TRUE. When TRUE, data that is sent from the local interface to the multicast group to
310 which the socket is joined, including data sent from the same socket, will be echoed to its receive buffer.
313 return SetOption(IPPROTO_IP
, IP_MULTICAST_LOOP
, &disable
, sizeof(disable
));
316 //network operations*************************************************************************************************
317 int JackNetWinSocket::SendTo(const void* buffer
, size_t nbytes
, int flags
)
319 return sendto(fSockfd
, reinterpret_cast<const char*>(buffer
), nbytes
, flags
, reinterpret_cast<SOCKADDR
*>(&fSendAddr
), sizeof(SOCKADDR
));
322 int JackNetWinSocket::SendTo(const void* buffer
, size_t nbytes
, int flags
, const char* ip
)
324 fSendAddr
.sin_addr
.s_addr
= inet_addr(ip
);
325 fSendAddr
.sin_port
= htons(fPort
);
326 return SendTo(buffer
, nbytes
, flags
);
329 int JackNetWinSocket::Send(const void* buffer
, size_t nbytes
, int flags
)
331 return send(fSockfd
, reinterpret_cast<const char*>(buffer
), nbytes
, flags
);
334 int JackNetWinSocket::RecvFrom(void* buffer
, size_t nbytes
, int flags
)
336 SOCKLEN addr_len
= sizeof(SOCKADDR
);
337 return recvfrom(fSockfd
, reinterpret_cast<char*>(buffer
), nbytes
, flags
, reinterpret_cast<SOCKADDR
*>(&fRecvAddr
), &addr_len
);
340 int JackNetWinSocket::Recv(void* buffer
, size_t nbytes
, int flags
)
342 return recv(fSockfd
, reinterpret_cast<char*>(buffer
), nbytes
, flags
);
345 int JackNetWinSocket::CatchHost(void* buffer
, size_t nbytes
, int flags
)
347 SOCKLEN addr_len
= sizeof(SOCKADDR
);
348 return recvfrom(fSockfd
, reinterpret_cast<char*>(buffer
), nbytes
, flags
, reinterpret_cast<SOCKADDR
*>(&fSendAddr
), &addr_len
);
351 net_error_t
JackNetWinSocket::GetError()
353 switch (NET_ERROR_CODE
)
361 case WSAECONNREFUSED
:
362 return NET_CONN_ERROR
;
364 return NET_CONN_ERROR
;
366 return NET_CONN_ERROR
;
367 case WSAECONNABORTED
:
368 return NET_CONN_ERROR
;
370 return NET_CONN_ERROR
;
371 case WSAEHOSTUNREACH
:
372 return NET_CONN_ERROR
;