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 );
103 /* Enable address reuse */
105 if ((res
= setsockopt( fSockfd
, SOL_SOCKET
, SO_REUSEADDR
, &on
, sizeof(on
))) < 0) {
106 StrError(NET_ERROR_CODE
);
112 int JackNetUnixSocket::Bind()
114 return bind ( fSockfd
, reinterpret_cast<socket_address_t
*> ( &fRecvAddr
), sizeof ( socket_address_t
) );
117 int JackNetUnixSocket::BindWith ( const char* ip
)
119 int addr_conv
= inet_aton ( ip
, &fRecvAddr
.sin_addr
);
125 int JackNetUnixSocket::BindWith ( int port
)
127 fRecvAddr
.sin_port
= htons ( port
);
131 int JackNetUnixSocket::Connect()
133 return connect ( fSockfd
, reinterpret_cast<socket_address_t
*> ( &fSendAddr
), sizeof ( socket_address_t
) );
136 int JackNetUnixSocket::ConnectTo ( const char* ip
)
138 int addr_conv
= inet_aton ( ip
, &fSendAddr
.sin_addr
);
144 void JackNetUnixSocket::Close()
151 void JackNetUnixSocket::Reset()
153 fSendAddr
.sin_family
= AF_INET
;
154 fSendAddr
.sin_port
= htons ( fPort
);
155 fSendAddr
.sin_addr
.s_addr
= htonl ( INADDR_ANY
);
156 memset ( &fSendAddr
.sin_zero
, 0, 8 );
157 fRecvAddr
.sin_family
= AF_INET
;
158 fRecvAddr
.sin_port
= htons ( fPort
);
159 fRecvAddr
.sin_addr
.s_addr
= htonl ( INADDR_ANY
);
160 memset ( &fRecvAddr
.sin_zero
, 0, 8 );
163 bool JackNetUnixSocket::IsSocket()
165 return ( fSockfd
) ? true : false;
168 //IP/PORT***********************************************************************************************************
169 void JackNetUnixSocket::SetPort ( int port
)
172 fSendAddr
.sin_port
= htons ( port
);
173 fRecvAddr
.sin_port
= htons ( port
);
176 int JackNetUnixSocket::GetPort()
181 //address***********************************************************************************************************
182 int JackNetUnixSocket::SetAddress ( const char* ip
, int port
)
184 int addr_conv
= inet_aton ( ip
, &fSendAddr
.sin_addr
);
187 fSendAddr
.sin_port
= htons ( port
);
191 char* JackNetUnixSocket::GetSendIP()
193 return inet_ntoa ( fSendAddr
.sin_addr
);
196 char* JackNetUnixSocket::GetRecvIP()
198 return inet_ntoa ( fRecvAddr
.sin_addr
);
201 //utility************************************************************************************************************
202 int JackNetUnixSocket::GetName ( char* name
)
204 return gethostname ( name
, 255 );
207 int JackNetUnixSocket::JoinMCastGroup ( const char* ip
)
209 struct ip_mreq multicast_req
;
210 inet_aton ( ip
, &multicast_req
.imr_multiaddr
);
211 multicast_req
.imr_interface
.s_addr
= htonl ( INADDR_ANY
);
212 return SetOption ( IPPROTO_IP
, IP_ADD_MEMBERSHIP
, &multicast_req
, sizeof ( multicast_req
) );
215 //options************************************************************************************************************
216 int JackNetUnixSocket::SetOption ( int level
, int optname
, const void* optval
, socklen_t optlen
)
218 return setsockopt ( fSockfd
, level
, optname
, optval
, optlen
);
221 int JackNetUnixSocket::GetOption ( int level
, int optname
, void* optval
, socklen_t
* optlen
)
223 return getsockopt ( fSockfd
, level
, optname
, optval
, optlen
);
226 //timeout************************************************************************************************************
228 #if defined(__sun__) || defined(sun)
229 int JackNetUnixSocket::SetTimeOut ( int us
)
234 if ((flags
= fcntl(fSockfd
, F_GETFL
, 0)) < 0) {
235 jack_error("JackNetUnixSocket::SetTimeOut error in fcntl F_GETFL");
240 if (fcntl(fSockfd
, F_SETFL
, flags
) < 0) {
241 jack_error("JackNetUnixSocket::SetTimeOut error in fcntl F_SETFL");
248 int JackNetUnixSocket::WaitRead()
256 tv
.tv_sec
= fTimeOut
/ 1000000;
257 tv
.tv_usec
= fTimeOut
% 1000000;
260 FD_SET(fSockfd
, &fdset
);
263 res
= select(fSockfd
+ 1, &fdset
, NULL
, NULL
, &tv
);
264 } while (res
< 0 && errno
== EINTR
);
268 } else if (res
== 0) {
277 int JackNetUnixSocket::WaitWrite()
285 tv
.tv_sec
= fTimeOut
/ 1000000;
286 tv
.tv_usec
= fTimeOut
% 1000000;
289 FD_SET(fSockfd
, &fdset
);
292 res
= select(fSockfd
+ 1, NULL
, &fdset
, NULL
, &tv
);
293 } while (res
< 0 && errno
== EINTR
);
297 } else if (res
== 0) {
307 int JackNetUnixSocket::SetTimeOut ( int us
)
309 jack_log ( "JackNetUnixSocket::SetTimeout %d usecs", us
);
311 //negative timeout, or exceding 10s, return
312 if ( ( us
< 0 ) || ( us
> 10000000 ) )
314 struct timeval timeout
;
320 timeout
.tv_usec
= us
;
325 float sec
= static_cast<float> ( us
) / 1000000.f
;
326 timeout
.tv_sec
= ( int ) sec
;
327 float usec
= ( sec
- static_cast<float> ( timeout
.tv_sec
) ) * 1000000;
328 timeout
.tv_usec
= ( int ) usec
;
330 return SetOption ( SOL_SOCKET
, SO_RCVTIMEO
, &timeout
, sizeof ( timeout
) );
334 //local loop**********************************************************************************************************
335 int JackNetUnixSocket::SetLocalLoop()
338 return SetOption ( IPPROTO_IP
, IP_MULTICAST_LOOP
, &disable
, sizeof ( disable
) );
341 //network operations**************************************************************************************************
342 int JackNetUnixSocket::SendTo ( const void* buffer
, size_t nbytes
, int flags
)
344 #if defined(__sun__) || defined(sun)
348 return sendto ( fSockfd
, buffer
, nbytes
, flags
, reinterpret_cast<socket_address_t
*> ( &fSendAddr
), sizeof ( socket_address_t
) );
351 int JackNetUnixSocket::SendTo ( const void* buffer
, size_t nbytes
, int flags
, const char* ip
)
353 int addr_conv
= inet_aton ( ip
, &fSendAddr
.sin_addr
);
356 #if defined(__sun__) || defined(sun)
360 return SendTo ( buffer
, nbytes
, flags
);
363 int JackNetUnixSocket::Send ( const void* buffer
, size_t nbytes
, int flags
)
365 #if defined(__sun__) || defined(sun)
369 return send ( fSockfd
, buffer
, nbytes
, flags
);
372 int JackNetUnixSocket::RecvFrom ( void* buffer
, size_t nbytes
, int flags
)
374 socklen_t addr_len
= sizeof ( socket_address_t
);
375 #if defined(__sun__) || defined(sun)
379 return recvfrom ( fSockfd
, buffer
, nbytes
, flags
, reinterpret_cast<socket_address_t
*> ( &fRecvAddr
), &addr_len
);
382 int JackNetUnixSocket::Recv ( void* buffer
, size_t nbytes
, int flags
)
384 #if defined(__sun__) || defined(sun)
388 return recv ( fSockfd
, buffer
, nbytes
, flags
);
391 int JackNetUnixSocket::CatchHost ( void* buffer
, size_t nbytes
, int flags
)
393 socklen_t addr_len
= sizeof ( socket_address_t
);
394 #if defined(__sun__) || defined(sun)
398 return recvfrom ( fSockfd
, buffer
, nbytes
, flags
, reinterpret_cast<socket_address_t
*> ( &fSendAddr
), &addr_len
);
401 net_error_t
JackNetUnixSocket::GetError()
417 return NET_CONN_ERROR
;