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;
65 //-----------------------------------------------------------------------------
66 // name: struct ck_socket_
68 //-----------------------------------------------------------------------------
73 struct sockaddr_in sock_in
;
80 //-----------------------------------------------------------------------------
81 // name: ck_udp_create()
82 // desc: create a udp socket
83 //-----------------------------------------------------------------------------
84 ck_socket
ck_udp_create( )
86 ck_socket sock
= NULL
;
88 #ifdef __PLATFORM_WIN32__
91 if( WSAStartup( MAKEWORD(1,1), &(g_wsd
) ) != 0 &&
92 WSAStartup( MAKEWORD(1,0), &(g_wsd
) ) != 0 )
94 fprintf( stderr
, "[chuck]: cannot start winsock, networking disabled...\n" );
102 sock
= (ck_socket
)checked_malloc( sizeof( struct ck_socket_
) );
103 sock
->sock
= socket( AF_INET
, SOCK_DGRAM
, 0 );
104 sock
->prot
= SOCK_DGRAM
;
112 //-----------------------------------------------------------------------------
113 // name: ck_tcp_create()
114 // desc: create a tcp socket
115 //-----------------------------------------------------------------------------
116 ck_socket
ck_tcp_create( int flags
)
118 ck_socket sock
= (ck_socket
)checked_malloc( sizeof( struct ck_socket_
) );
119 int nd
= 1; int ru
= 1;
121 #ifdef __PLATFORM_WIN32__
124 if( WSAStartup( MAKEWORD(1,1), &(g_wsd
) ) != 0 &&
125 WSAStartup( MAKEWORD(1,0), &(g_wsd
) ) != 0 )
127 fprintf( stderr
, "[chuck]: cannot start winsock, networking disabled...\n" );
135 sock
->sock
= socket( AF_INET
, SOCK_STREAM
, 0 );
136 sock
->prot
= SOCK_STREAM
;
139 setsockopt( sock
->sock
, SOL_SOCKET
, SO_REUSEADDR
, (const char *)&ru
, sizeof(ru
) );
140 // setsockopt( sock->sock, SOL_SOCKET, SO_REUSEPORT, (const char *)&ru, sizeof(ru) );
141 setsockopt( sock
->sock
, IPPROTO_TCP
, TCP_NODELAY
, (const char *)&nd
, sizeof(nd
) );
149 //-----------------------------------------------------------------------------
150 // name: ck_connect2()
151 // desc: connect to a server
152 //-----------------------------------------------------------------------------
153 t_CKBOOL
ck_connect2( ck_socket sock
, const struct sockaddr
* addr
, int size
)
155 int ret
= connect( sock
->sock
, addr
, size
);
163 //-----------------------------------------------------------------------------
164 // name: ck_connect()
165 // desc: connect to a server
166 //-----------------------------------------------------------------------------
167 t_CKBOOL
ck_connect( ck_socket sock
, const char * hostname
, int port
)
170 struct hostent
* host
;
172 #ifdef __PLATFORM_WIN32__
173 memset( &sock
->sock_in
, 0, sizeof(struct sockaddr_in
) );
175 bzero( &sock
->sock_in
, sizeof(struct sockaddr_in
) );
178 sock
->sock_in
.sin_family
= AF_INET
;
179 sock
->sock_in
.sin_port
= htons( (unsigned short)port
);
181 host
= gethostbyname( hostname
);
184 sock
->sock_in
.sin_addr
.s_addr
= inet_addr( hostname
);
185 if( sock
->sock_in
.sin_addr
.s_addr
== -1 )
190 #ifdef __PLATFORM_WIN32__
191 memcpy( (char *)&sock
->sock_in
.sin_addr
, host
->h_addr
, host
->h_length
);
193 bcopy( host
->h_addr
, (char *)&sock
->sock_in
.sin_addr
, host
->h_length
);
197 ret
= ck_connect2( sock
, (struct sockaddr
*)&sock
->sock_in
,
198 sizeof( struct sockaddr_in
) );
206 //-----------------------------------------------------------------------------
208 // desc: bind to a port
209 //-----------------------------------------------------------------------------
210 t_CKBOOL
ck_bind( ck_socket sock
, int port
)
214 #ifdef __PLATFORM_WIN32__
215 memset( &sock
->sock_in
, 0, sizeof(struct sockaddr_in
) );
217 bzero( &sock
->sock_in
, sizeof(struct sockaddr_in
) );
220 sock
->sock_in
.sin_family
= AF_INET
;
221 sock
->sock_in
.sin_port
= htons( (unsigned short)port
);
222 sock
->sock_in
.sin_addr
.s_addr
= htonl( INADDR_ANY
);
224 ret
= bind( sock
->sock
, (struct sockaddr
*)&sock
->sock_in
,
225 sizeof(struct sockaddr_in
));
233 //-----------------------------------------------------------------------------
236 //-----------------------------------------------------------------------------
237 t_CKBOOL
ck_listen( ck_socket sock
, int backlog
)
241 if( sock
->prot
!= SOCK_STREAM
) return FALSE
;
242 ret
= listen( sock
->sock
, backlog
);
250 //-----------------------------------------------------------------------------
253 //-----------------------------------------------------------------------------
254 ck_socket
ck_accept( ck_socket sock
)
259 if( sock
->prot
!= SOCK_STREAM
) return NULL
;
260 client
= (ck_socket
)checked_malloc( sizeof( struct ck_socket_
) );
261 client
->len
= sizeof( client
->sock_in
);
262 client
->sock
= accept( sock
->sock
, (struct sockaddr
*)&client
->sock_in
,
264 if( client
->sock
<= 0 ) goto error
;
265 client
->prot
= SOCK_STREAM
;
266 setsockopt( client
->sock
, IPPROTO_TCP
, TCP_NODELAY
, (const char *)&nd
, sizeof(nd
) );
268 #ifdef __PLATFORM_WIN32__
282 //-----------------------------------------------------------------------------
284 // desc: send a datagram
285 //-----------------------------------------------------------------------------
286 int ck_send( ck_socket sock
, const char * buffer
, int len
)
288 return send( sock
->sock
, buffer
, len
, 0 );
294 //-----------------------------------------------------------------------------
296 // desc: send a datagram
297 //-----------------------------------------------------------------------------
298 int ck_sendto( ck_socket sock
, const char * buffer
, int len
,
299 const struct sockaddr
* to
, int tolen
)
301 if( sock
->prot
== SOCK_STREAM
) return 0;
302 else return sendto( sock
->sock
, buffer
, len
, 0, to
, tolen
);
308 //-----------------------------------------------------------------------------
309 // name: ck_recvfrom()
310 // desc: recv a datagram
311 //-----------------------------------------------------------------------------
312 int ck_recvfrom( ck_socket sock
, char * buffer
, int len
,
313 struct sockaddr
* from
, int * fromlen
)
315 if( sock
->prot
== SOCK_STREAM
)
317 memset( buffer
, 0, len
);
320 else return recvfrom( sock
->sock
, buffer
, len
, 0, from
, (unsigned int *)fromlen
);
326 //-----------------------------------------------------------------------------
328 // desc: recv a datagram
329 //-----------------------------------------------------------------------------
330 int ck_recv( ck_socket sock
, char * buffer
, int len
)
332 if( sock
->prot
== SOCK_STREAM
)
339 ret
= recv( sock
->sock
, p
, togo
, 0 );
340 if( ret
< 0 ) return 0;
346 else return recv( sock
->sock
, buffer
, len
, 0);
352 //-----------------------------------------------------------------------------
353 // name: ck_send_timeout()
355 //-----------------------------------------------------------------------------
356 int ck_send_timeout( ck_socket sock
, long sec
, long usec
)
362 return 0 == setsockopt( sock
->sock
, SOL_SOCKET
, SO_SNDTIMEO
, (const char *)&t
, sizeof(t
) );
368 //-----------------------------------------------------------------------------
369 // name: ck_recv_timeout()
371 //-----------------------------------------------------------------------------
372 int ck_recv_timeout( ck_socket sock
, long sec
, long usec
)
378 return 0 == setsockopt( sock
->sock
, SOL_SOCKET
, SO_RCVTIMEO
, (const char *)&t
, sizeof(t
) );
384 //-----------------------------------------------------------------------------
387 //-----------------------------------------------------------------------------
388 void ck_close( ck_socket sock
)
392 #ifdef __PLATFORM_WIN32__
393 closesocket( sock
->sock
);
400 #ifdef __PLATFORM_WIN32__
405 if( g_init
== 0 ) WSACleanup();