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 "JackNetUnixSocket.h"
26 //utility *********************************************************************************************************
27 int GetHostName ( char * name
, int size
)
29 if ( gethostname ( name
, size
) == SOCKET_ERROR
)
31 jack_error ( "Can't get 'hostname' : %s", strerror ( NET_ERROR_CODE
) );
32 strcpy ( name
, "default" );
38 //construct/destruct***********************************************************************************************
39 JackNetUnixSocket::JackNetUnixSocket()
44 fSendAddr
.sin_family
= AF_INET
;
45 fSendAddr
.sin_addr
.s_addr
= htonl ( INADDR_ANY
);
46 memset ( &fSendAddr
.sin_zero
, 0, 8 );
47 fRecvAddr
.sin_family
= AF_INET
;
48 fRecvAddr
.sin_addr
.s_addr
= htonl ( INADDR_ANY
);
49 memset ( &fRecvAddr
.sin_zero
, 0, 8 );
52 JackNetUnixSocket::JackNetUnixSocket ( const char* ip
, int port
)
57 fSendAddr
.sin_family
= AF_INET
;
58 fSendAddr
.sin_port
= htons ( port
);
59 inet_aton ( ip
, &fSendAddr
.sin_addr
);
60 memset ( &fSendAddr
.sin_zero
, 0, 8 );
61 fRecvAddr
.sin_family
= AF_INET
;
62 fRecvAddr
.sin_port
= htons ( port
);
63 fRecvAddr
.sin_addr
.s_addr
= htonl ( INADDR_ANY
);
64 memset ( &fRecvAddr
.sin_zero
, 0, 8 );
67 JackNetUnixSocket::JackNetUnixSocket ( const JackNetUnixSocket
& socket
)
72 fSendAddr
= socket
.fSendAddr
;
73 fRecvAddr
= socket
.fRecvAddr
;
76 JackNetUnixSocket::~JackNetUnixSocket()
81 JackNetUnixSocket
& JackNetUnixSocket::operator= ( const JackNetUnixSocket
& socket
)
83 if ( this != &socket
)
87 fSendAddr
= socket
.fSendAddr
;
88 fRecvAddr
= socket
.fRecvAddr
;
93 //socket***********************************************************************************************************
94 int JackNetUnixSocket::NewSocket()
101 fSockfd
= socket ( AF_INET
, SOCK_DGRAM
, 0 );
105 int JackNetUnixSocket::Bind()
107 return bind ( fSockfd
, reinterpret_cast<socket_address_t
*> ( &fRecvAddr
), sizeof ( socket_address_t
) );
110 int JackNetUnixSocket::BindWith ( const char* ip
)
112 int addr_conv
= inet_aton ( ip
, &fRecvAddr
.sin_addr
);
118 int JackNetUnixSocket::BindWith ( int port
)
120 fRecvAddr
.sin_port
= htons ( port
);
124 int JackNetUnixSocket::Connect()
126 return connect ( fSockfd
, reinterpret_cast<socket_address_t
*> ( &fSendAddr
), sizeof ( socket_address_t
) );
129 int JackNetUnixSocket::ConnectTo ( const char* ip
)
131 int addr_conv
= inet_aton ( ip
, &fSendAddr
.sin_addr
);
137 void JackNetUnixSocket::Close()
144 void JackNetUnixSocket::Reset()
146 fSendAddr
.sin_family
= AF_INET
;
147 fSendAddr
.sin_port
= htons ( fPort
);
148 fSendAddr
.sin_addr
.s_addr
= htonl ( INADDR_ANY
);
149 memset ( &fSendAddr
.sin_zero
, 0, 8 );
150 fRecvAddr
.sin_family
= AF_INET
;
151 fRecvAddr
.sin_port
= htons ( fPort
);
152 fRecvAddr
.sin_addr
.s_addr
= htonl ( INADDR_ANY
);
153 memset ( &fRecvAddr
.sin_zero
, 0, 8 );
156 bool JackNetUnixSocket::IsSocket()
158 return ( fSockfd
) ? true : false;
161 //IP/PORT***********************************************************************************************************
162 void JackNetUnixSocket::SetPort ( int port
)
165 fSendAddr
.sin_port
= htons ( port
);
166 fRecvAddr
.sin_port
= htons ( port
);
169 int JackNetUnixSocket::GetPort()
174 //address***********************************************************************************************************
175 int JackNetUnixSocket::SetAddress ( const char* ip
, int port
)
177 int addr_conv
= inet_aton ( ip
, &fSendAddr
.sin_addr
);
180 fSendAddr
.sin_port
= htons ( port
);
184 char* JackNetUnixSocket::GetSendIP()
186 return inet_ntoa ( fSendAddr
.sin_addr
);
189 char* JackNetUnixSocket::GetRecvIP()
191 return inet_ntoa ( fRecvAddr
.sin_addr
);
194 //utility************************************************************************************************************
195 int JackNetUnixSocket::GetName ( char* name
)
197 return gethostname ( name
, 255 );
200 int JackNetUnixSocket::JoinMCastGroup ( const char* ip
)
202 struct ip_mreq multicast_req
;
203 inet_aton ( ip
, &multicast_req
.imr_multiaddr
);
204 multicast_req
.imr_interface
.s_addr
= htonl ( INADDR_ANY
);
205 return SetOption ( IPPROTO_IP
, IP_ADD_MEMBERSHIP
, &multicast_req
, sizeof ( multicast_req
) );
208 //options************************************************************************************************************
209 int JackNetUnixSocket::SetOption ( int level
, int optname
, const void* optval
, socklen_t optlen
)
211 return setsockopt ( fSockfd
, level
, optname
, optval
, optlen
);
214 int JackNetUnixSocket::GetOption ( int level
, int optname
, void* optval
, socklen_t
* optlen
)
216 return getsockopt ( fSockfd
, level
, optname
, optval
, optlen
);
219 //timeout************************************************************************************************************
221 #if defined(__sun__) || defined(sun)
222 int JackNetUnixSocket::SetTimeOut ( int us
)
227 if ((flags
= fcntl(fSockfd
, F_GETFL
, 0)) < 0) {
228 jack_error("JackNetUnixSocket::SetTimeOut error in fcntl F_GETFL");
233 if (fcntl(fSockfd
, F_SETFL
, flags
) < 0) {
234 jack_error("JackNetUnixSocket::SetTimeOut error in fcntl F_SETFL");
241 int JackNetUnixSocket::WaitRead()
249 tv
.tv_sec
= fTimeOut
/ 1000000;
250 tv
.tv_usec
= fTimeOut
% 1000000;
253 FD_SET(fSockfd
, &fdset
);
256 res
= select(fSockfd
+ 1, &fdset
, NULL
, NULL
, &tv
);
257 } while (res
< 0 && errno
== EINTR
);
261 } else if (res
== 0) {
270 int JackNetUnixSocket::WaitWrite()
278 tv
.tv_sec
= fTimeOut
/ 1000000;
279 tv
.tv_usec
= fTimeOut
% 1000000;
282 FD_SET(fSockfd
, &fdset
);
285 res
= select(fSockfd
+ 1, NULL
, &fdset
, NULL
, &tv
);
286 } while (res
< 0 && errno
== EINTR
);
290 } else if (res
== 0) {
300 int JackNetUnixSocket::SetTimeOut ( int us
)
302 jack_log ( "JackNetUnixSocket::SetTimeout %d usecs", us
);
304 //negative timeout, or exceding 10s, return
305 if ( ( us
< 0 ) || ( us
> 10000000 ) )
307 struct timeval timeout
;
313 timeout
.tv_usec
= us
;
318 float sec
= static_cast<float> ( us
) / 1000000.f
;
319 timeout
.tv_sec
= ( int ) sec
;
320 float usec
= ( sec
- static_cast<float> ( timeout
.tv_sec
) ) * 1000000;
321 timeout
.tv_usec
= ( int ) usec
;
323 return SetOption ( SOL_SOCKET
, SO_RCVTIMEO
, &timeout
, sizeof ( timeout
) );
327 //local loop**********************************************************************************************************
328 int JackNetUnixSocket::SetLocalLoop()
331 return SetOption ( IPPROTO_IP
, IP_MULTICAST_LOOP
, &disable
, sizeof ( disable
) );
334 //network operations**************************************************************************************************
335 int JackNetUnixSocket::SendTo ( const void* buffer
, size_t nbytes
, int flags
)
337 #if defined(__sun__) || defined(sun)
341 return sendto ( fSockfd
, buffer
, nbytes
, flags
, reinterpret_cast<socket_address_t
*> ( &fSendAddr
), sizeof ( socket_address_t
) );
344 int JackNetUnixSocket::SendTo ( const void* buffer
, size_t nbytes
, int flags
, const char* ip
)
346 int addr_conv
= inet_aton ( ip
, &fSendAddr
.sin_addr
);
349 #if defined(__sun__) || defined(sun)
353 return SendTo ( buffer
, nbytes
, flags
);
356 int JackNetUnixSocket::Send ( const void* buffer
, size_t nbytes
, int flags
)
358 #if defined(__sun__) || defined(sun)
362 return send ( fSockfd
, buffer
, nbytes
, flags
);
365 int JackNetUnixSocket::RecvFrom ( void* buffer
, size_t nbytes
, int flags
)
367 socklen_t addr_len
= sizeof ( socket_address_t
);
368 #if defined(__sun__) || defined(sun)
372 return recvfrom ( fSockfd
, buffer
, nbytes
, flags
, reinterpret_cast<socket_address_t
*> ( &fRecvAddr
), &addr_len
);
375 int JackNetUnixSocket::Recv ( void* buffer
, size_t nbytes
, int flags
)
377 #if defined(__sun__) || defined(sun)
381 return recv ( fSockfd
, buffer
, nbytes
, flags
);
384 int JackNetUnixSocket::CatchHost ( void* buffer
, size_t nbytes
, int flags
)
386 socklen_t addr_len
= sizeof ( socket_address_t
);
387 #if defined(__sun__) || defined(sun)
391 return recvfrom ( fSockfd
, buffer
, nbytes
, flags
, reinterpret_cast<socket_address_t
*> ( &fSendAddr
), &addr_len
);
394 net_error_t
JackNetUnixSocket::GetError()
410 return NET_CONN_ERROR
;