1 /*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.cs.princeton.edu/
7 http://soundlab.cs.princeton.edu/
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
26 // name: util_network.c
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
32 // originally randy_socket
33 // author: Peng Bi (pbi@cs.princeton.edu)
34 // Ge Wang (gewang@cs.princeton.edu)
36 //-----------------------------------------------------------------------------
37 #include "util_network.h"
38 #include "chuck_utils.h"
41 #if defined(__PLATFORM_WIN32__)
44 #include <sys/types.h>
45 #include <sys/socket.h>
48 #include <netinet/in.h>
49 #include <netinet/tcp.h>
50 #include <arpa/inet.h>
57 #ifdef __PLATFORM_WIN32__
59 static int g_init
= 0;
63 #define socklen_t unsigned int
67 //-----------------------------------------------------------------------------
68 // name: struct ck_socket_
70 //-----------------------------------------------------------------------------
75 struct sockaddr_in sock_in
;
82 //-----------------------------------------------------------------------------
83 // name: ck_udp_create()
84 // desc: create a udp socket
85 //-----------------------------------------------------------------------------
86 ck_socket
ck_udp_create( )
88 ck_socket sock
= NULL
;
90 #ifdef __PLATFORM_WIN32__
93 if( WSAStartup( MAKEWORD(1,1), &(g_wsd
) ) != 0 &&
94 WSAStartup( MAKEWORD(1,0), &(g_wsd
) ) != 0 )
96 fprintf( stderr
, "[chuck]: cannot start winsock, networking disabled...\n" );
104 sock
= (ck_socket
)checked_malloc( sizeof( struct ck_socket_
) );
105 sock
->sock
= socket( AF_INET
, SOCK_DGRAM
, 0 );
106 sock
->prot
= SOCK_DGRAM
;
114 //-----------------------------------------------------------------------------
115 // name: ck_tcp_create()
116 // desc: create a tcp socket
117 //-----------------------------------------------------------------------------
118 ck_socket
ck_tcp_create( int flags
)
120 ck_socket sock
= (ck_socket
)checked_malloc( sizeof( struct ck_socket_
) );
121 int nd
= 1; int ru
= 1;
123 #ifdef __PLATFORM_WIN32__
126 if( WSAStartup( MAKEWORD(1,1), &(g_wsd
) ) != 0 &&
127 WSAStartup( MAKEWORD(1,0), &(g_wsd
) ) != 0 )
129 fprintf( stderr
, "[chuck]: cannot start winsock, networking disabled...\n" );
137 sock
->sock
= socket( AF_INET
, SOCK_STREAM
, 0 );
138 sock
->prot
= SOCK_STREAM
;
141 setsockopt( sock
->sock
, SOL_SOCKET
, SO_REUSEADDR
, (const char *)&ru
, sizeof(ru
) );
142 // setsockopt( sock->sock, SOL_SOCKET, SO_REUSEPORT, (const char *)&ru, sizeof(ru) );
143 setsockopt( sock
->sock
, IPPROTO_TCP
, TCP_NODELAY
, (const char *)&nd
, sizeof(nd
) );
151 //-----------------------------------------------------------------------------
152 // name: ck_connect2()
153 // desc: connect to a server
154 //-----------------------------------------------------------------------------
155 t_CKBOOL
ck_connect2( ck_socket sock
, const struct sockaddr
* addr
, int size
)
157 int ret
= connect( sock
->sock
, addr
, size
);
165 //-----------------------------------------------------------------------------
166 // name: ck_connect()
167 // desc: connect to a server
168 //-----------------------------------------------------------------------------
169 t_CKBOOL
ck_connect( ck_socket sock
, const char * hostname
, int port
)
172 struct hostent
* host
;
174 #ifdef __PLATFORM_WIN32__
175 memset( &sock
->sock_in
, 0, sizeof(struct sockaddr_in
) );
177 bzero( &sock
->sock_in
, sizeof(struct sockaddr_in
) );
180 sock
->sock_in
.sin_family
= AF_INET
;
181 sock
->sock_in
.sin_port
= htons( (unsigned short)abs(port
) );
183 host
= gethostbyname( hostname
);
186 sock
->sock_in
.sin_addr
.s_addr
= inet_addr( hostname
);
187 if( sock
->sock_in
.sin_addr
.s_addr
== -1 )
192 #ifdef __PLATFORM_WIN32__
193 memcpy( (char *)&sock
->sock_in
.sin_addr
, host
->h_addr
, host
->h_length
);
195 bcopy( host
->h_addr
, (char *)&sock
->sock_in
.sin_addr
, host
->h_length
);
202 ret
= ck_connect2( sock
, (struct sockaddr
*)&sock
->sock_in
,
203 sizeof( struct sockaddr_in
) );
211 //-----------------------------------------------------------------------------
213 // desc: bind to a port
214 //-----------------------------------------------------------------------------
215 t_CKBOOL
ck_bind( ck_socket sock
, int port
)
219 #ifdef __PLATFORM_WIN32__
220 memset( &sock
->sock_in
, 0, sizeof(struct sockaddr_in
) );
222 bzero( &sock
->sock_in
, sizeof(struct sockaddr_in
) );
225 sock
->sock_in
.sin_family
= AF_INET
;
226 sock
->sock_in
.sin_port
= htons( (unsigned short)port
);
227 sock
->sock_in
.sin_addr
.s_addr
= htonl( INADDR_ANY
);
229 ret
= bind( sock
->sock
, (struct sockaddr
*)&sock
->sock_in
,
230 sizeof(struct sockaddr_in
));
238 //-----------------------------------------------------------------------------
241 //-----------------------------------------------------------------------------
242 t_CKBOOL
ck_listen( ck_socket sock
, int backlog
)
246 if( sock
->prot
!= SOCK_STREAM
) return FALSE
;
247 ret
= listen( sock
->sock
, backlog
);
255 //-----------------------------------------------------------------------------
258 //-----------------------------------------------------------------------------
259 ck_socket
ck_accept( ck_socket sock
)
264 if( sock
->prot
!= SOCK_STREAM
) return NULL
;
265 client
= (ck_socket
)checked_malloc( sizeof( struct ck_socket_
) );
266 client
->len
= sizeof( client
->sock_in
);
267 client
->sock
= accept( sock
->sock
, (struct sockaddr
*)&client
->sock_in
,
269 if( client
->sock
<= 0 ) goto error
;
270 client
->prot
= SOCK_STREAM
;
271 setsockopt( client
->sock
, IPPROTO_TCP
, TCP_NODELAY
, (const char *)&nd
, sizeof(nd
) );
273 #ifdef __PLATFORM_WIN32__
287 //-----------------------------------------------------------------------------
289 // desc: send a datagram
290 //-----------------------------------------------------------------------------
291 int ck_send( ck_socket sock
, const char * buffer
, int len
)
293 return send( sock
->sock
, buffer
, len
, 0 );
299 //-----------------------------------------------------------------------------
301 // desc: send a datagram
302 //-----------------------------------------------------------------------------
303 int ck_send2( ck_socket sock
, const char * buffer
, int len
)
305 return sendto( sock
->sock
, buffer
, len
, 0,
306 (struct sockaddr
*)&sock
->sock_in
, sizeof(struct sockaddr_in
) );
312 //-----------------------------------------------------------------------------
314 // desc: send a datagram
315 //-----------------------------------------------------------------------------
316 int ck_sendto( ck_socket sock
, const char * buffer
, int len
,
317 const struct sockaddr
* to
, int tolen
)
319 if( sock
->prot
== SOCK_STREAM
) return 0;
320 else return sendto( sock
->sock
, buffer
, len
, 0, to
, tolen
);
326 //-----------------------------------------------------------------------------
327 // name: ck_recvfrom()
328 // desc: recv a datagram
329 //-----------------------------------------------------------------------------
330 int ck_recvfrom( ck_socket sock
, char * buffer
, int len
,
331 struct sockaddr
* from
, int * fromlen
)
333 if( sock
->prot
== SOCK_STREAM
)
335 memset( buffer
, 0, len
);
338 else return recvfrom( sock
->sock
, buffer
, len
, 0, from
, (unsigned int *)fromlen
);
344 //-----------------------------------------------------------------------------
346 // desc: recv a datagram
347 //-----------------------------------------------------------------------------
348 int ck_recv( ck_socket sock
, char * buffer
, int len
)
350 if( sock
->prot
== SOCK_STREAM
)
357 ret
= recv( sock
->sock
, p
, togo
, 0 );
358 if( ret
< 0 ) return 0; // negative is an error message
359 if( ret
== 0 ) return len
- togo
; // zero is end-of-transmission
365 else return recv( sock
->sock
, buffer
, len
, 0 );
371 //-----------------------------------------------------------------------------
373 // desc: recv a datagram
374 //-----------------------------------------------------------------------------
375 int ck_recv2( ck_socket sock
, char * buffer
, int len
)
377 struct sockaddr_in from
;
379 memset( &from
, 0, sizeof(from
) );
380 flen
= sizeof(struct sockaddr_in
);
381 return recvfrom( sock
->sock
, buffer
, len
, 0, (struct sockaddr
*)&from
, &flen
);
387 //-----------------------------------------------------------------------------
388 // name: ck_send_timeout()
390 //-----------------------------------------------------------------------------
391 int ck_send_timeout( ck_socket sock
, long sec
, long usec
)
397 return 0 == setsockopt( sock
->sock
, SOL_SOCKET
, SO_SNDTIMEO
, (const char *)&t
, sizeof(t
) );
403 //-----------------------------------------------------------------------------
404 // name: ck_recv_timeout()
406 //-----------------------------------------------------------------------------
407 int ck_recv_timeout( ck_socket sock
, long sec
, long usec
)
413 return 0 == setsockopt( sock
->sock
, SOL_SOCKET
, SO_RCVTIMEO
, (const char *)&t
, sizeof(t
) );
419 //-----------------------------------------------------------------------------
422 //-----------------------------------------------------------------------------
423 void ck_close( ck_socket sock
)
427 #ifdef __PLATFORM_WIN32__
428 closesocket( sock
->sock
);
435 #ifdef __PLATFORM_WIN32__
440 if( g_init
== 0 ) WSACleanup();