source: osgVisual/trunk/src/cluster/enet/win32.c @ 317

Last change on this file since 317 was 65, checked in by Torben Dannhauer, 14 years ago

new cluster implementation added: ENet
ENet is a reliable UDP implementation with quite simple usage and high performance for transmission with small or medium size packet.

File size: 8.0 KB
Line 
1/**
2 @file  win32.c
3 @brief ENet Win32 system specific functions
4*/
5#ifdef WIN32
6
7#include <time.h>
8#define ENET_BUILDING_LIB 1
9#include "enet/enet.h"
10
11static enet_uint32 timeBase = 0;
12
13int
14enet_initialize (void)
15{
16    WORD versionRequested = MAKEWORD (1, 1);
17    WSADATA wsaData;
18   
19    if (WSAStartup (versionRequested, & wsaData))
20       return -1;
21
22    if (LOBYTE (wsaData.wVersion) != 1||
23        HIBYTE (wsaData.wVersion) != 1)
24    {
25       WSACleanup ();
26       
27       return -1;
28    }
29
30    timeBeginPeriod (1);
31
32    return 0;
33}
34
35void
36enet_deinitialize (void)
37{
38    timeEndPeriod (1);
39
40    WSACleanup ();
41}
42
43enet_uint32
44enet_time_get (void)
45{
46    return (enet_uint32) timeGetTime () - timeBase;
47}
48
49void
50enet_time_set (enet_uint32 newTimeBase)
51{
52    timeBase = (enet_uint32) timeGetTime () - newTimeBase;
53}
54
55int
56enet_address_set_host (ENetAddress * address, const char * name)
57{
58    struct hostent * hostEntry;
59
60    hostEntry = gethostbyname (name);
61    if (hostEntry == NULL ||
62        hostEntry -> h_addrtype != AF_INET)
63    {
64        unsigned long host = inet_addr (name);
65        if (host == INADDR_NONE)
66            return -1;
67        address -> host = host;
68        return 0;
69    }
70
71    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
72
73    return 0;
74}
75
76int
77enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
78{
79    char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
80    if (addr == NULL)
81        return -1;
82    strncpy (name, addr, nameLength);
83    return 0;
84}
85
86int
87enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
88{
89    struct in_addr in;
90    struct hostent * hostEntry;
91   
92    in.s_addr = address -> host;
93   
94    hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
95    if (hostEntry == NULL)
96      return enet_address_get_host_ip (address, name, nameLength);
97
98    strncpy (name, hostEntry -> h_name, nameLength);
99
100    return 0;
101}
102
103int
104enet_socket_bind (ENetSocket socket, const ENetAddress * address)
105{
106    struct sockaddr_in sin;
107
108    memset (& sin, 0, sizeof (struct sockaddr_in));
109
110    sin.sin_family = AF_INET;
111
112    if (address != NULL)
113    {
114       sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
115       sin.sin_addr.s_addr = address -> host;
116    }
117    else
118    {
119       sin.sin_port = 0;
120       sin.sin_addr.s_addr = INADDR_ANY;
121    }
122
123    return bind (socket,
124                 (struct sockaddr *) & sin,
125                 sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
126}
127
128int
129enet_socket_listen (ENetSocket socket, int backlog)
130{
131    return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0;
132}
133
134ENetSocket
135enet_socket_create (ENetSocketType type)
136{
137    return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
138}
139
140int
141enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
142{
143    int result = SOCKET_ERROR;
144    switch (option)
145    {
146        case ENET_SOCKOPT_NONBLOCK:
147        {
148            u_long nonBlocking = (u_long) value;
149            result = ioctlsocket (socket, FIONBIO, & nonBlocking);
150            break;
151        }
152
153        case ENET_SOCKOPT_BROADCAST:
154            result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
155            break;
156
157        case ENET_SOCKOPT_REUSEADDR:
158            result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
159            break;
160
161        case ENET_SOCKOPT_RCVBUF:
162            result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
163            break;
164
165        case ENET_SOCKOPT_SNDBUF:
166            result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
167            break;
168
169        default:
170            break;
171    }
172    return result == SOCKET_ERROR ? -1 : 0;
173}
174
175int
176enet_socket_connect (ENetSocket socket, const ENetAddress * address)
177{
178    struct sockaddr_in sin;
179
180    memset (& sin, 0, sizeof (struct sockaddr_in));
181
182    sin.sin_family = AF_INET;
183    sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
184    sin.sin_addr.s_addr = address -> host;
185
186    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
187}
188
189ENetSocket
190enet_socket_accept (ENetSocket socket, ENetAddress * address)
191{
192    SOCKET result;
193    struct sockaddr_in sin;
194    int sinLength = sizeof (struct sockaddr_in);
195
196    result = accept (socket, 
197                     address != NULL ? (struct sockaddr *) & sin : NULL, 
198                     address != NULL ? & sinLength : NULL);
199
200    if (result == INVALID_SOCKET)
201      return ENET_SOCKET_NULL;
202
203    if (address != NULL)
204    {
205        address -> host = (enet_uint32) sin.sin_addr.s_addr;
206        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
207    }
208
209    return result;
210}
211
212void
213enet_socket_destroy (ENetSocket socket)
214{
215    closesocket (socket);
216}
217
218int
219enet_socket_send (ENetSocket socket,
220                  const ENetAddress * address,
221                  const ENetBuffer * buffers,
222                  size_t bufferCount)
223{
224    struct sockaddr_in sin;
225    DWORD sentLength;
226
227    if (address != NULL)
228    {
229        memset (& sin, 0, sizeof (struct sockaddr_in));
230
231        sin.sin_family = AF_INET;
232        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
233        sin.sin_addr.s_addr = address -> host;
234    }
235
236    if (WSASendTo (socket, 
237                   (LPWSABUF) buffers,
238                   (DWORD) bufferCount,
239                   & sentLength,
240                   0,
241                   address != NULL ? (struct sockaddr *) & sin : 0,
242                   address != NULL ? sizeof (struct sockaddr_in) : 0,
243                   NULL,
244                   NULL) == SOCKET_ERROR)
245    {
246       if (WSAGetLastError () == WSAEWOULDBLOCK)
247         return 0;
248
249       return -1;
250    }
251
252    return (int) sentLength;
253}
254
255int
256enet_socket_receive (ENetSocket socket,
257                     ENetAddress * address,
258                     ENetBuffer * buffers,
259                     size_t bufferCount)
260{
261    INT sinLength = sizeof (struct sockaddr_in);
262    DWORD flags = 0,
263          recvLength;
264    struct sockaddr_in sin;
265
266    if (WSARecvFrom (socket,
267                     (LPWSABUF) buffers,
268                     (DWORD) bufferCount,
269                     & recvLength,
270                     & flags,
271                     address != NULL ? (struct sockaddr *) & sin : NULL,
272                     address != NULL ? & sinLength : NULL,
273                     NULL,
274                     NULL) == SOCKET_ERROR)
275    {
276       switch (WSAGetLastError ())
277       {
278       case WSAEWOULDBLOCK:
279       case WSAECONNRESET:
280          return 0;
281       }
282
283       return -1;
284    }
285
286    if (flags & MSG_PARTIAL)
287      return -1;
288
289    if (address != NULL)
290    {
291        address -> host = (enet_uint32) sin.sin_addr.s_addr;
292        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
293    }
294
295    return (int) recvLength;
296}
297
298int
299enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
300{
301    struct timeval timeVal;
302
303    timeVal.tv_sec = timeout / 1000;
304    timeVal.tv_usec = (timeout % 1000) * 1000;
305
306    return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
307}
308
309int
310enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
311{
312    fd_set readSet, writeSet;
313    struct timeval timeVal;
314    int selectCount;
315   
316    timeVal.tv_sec = timeout / 1000;
317    timeVal.tv_usec = (timeout % 1000) * 1000;
318   
319    FD_ZERO (& readSet);
320    FD_ZERO (& writeSet);
321
322    if (* condition & ENET_SOCKET_WAIT_SEND)
323      FD_SET (socket, & writeSet);
324
325    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
326      FD_SET (socket, & readSet);
327
328    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
329
330    if (selectCount < 0)
331      return -1;
332
333    * condition = ENET_SOCKET_WAIT_NONE;
334
335    if (selectCount == 0)
336      return 0;
337
338    if (FD_ISSET (socket, & writeSet))
339      * condition |= ENET_SOCKET_WAIT_SEND;
340   
341    if (FD_ISSET (socket, & readSet))
342      * condition |= ENET_SOCKET_WAIT_RECEIVE;
343
344    return 0;
345} 
346
347#endif
348
Note: See TracBrowser for help on using the repository browser.