source: libcf/trunk/src/cf_socket.c@ 5

Last change on this file since 5 was 5, checked in by cheese, 11 years ago

#1 add windows project and fix build compatibility

File size: 5.4 KB
Line 
1/**
2 * cf_socket.c
3 */
4#include "cf_socket.h"
5#include "cf_local.h"
6
7#ifdef _WIN32
8# include <WinSock2.h>
9# pragma comment (lib, "ws2_32.lib")
10# define close(__sock) closesocket(__sock)
11# define sa_family_t unsigned short
12#else
13# include <netinet/in.h>
14# include <sys/socket.h>
15# include <arpa/inet.h>
16# include <netdb.h>
17# include <unistd.h>
18#endif
19
20#include <string.h>
21
22#define CHECK_SOCKET_INIT() \
23 if (!CF_Socket_IsInitialized ()) \
24 return CF_ERROR_SOCKET_NOT_INITIALIZED
25
26#define CHECK_INVALID_SOCKET(__sock) \
27 if (__sock < 0) \
28 return CF_ERROR_SOCKET_INVALID_SOCKET
29
30E_CF_BOOL gInitialized = CF_FALSE;
31
32E_CF_BOOL
33CF_Socket_IsInitialized (void)
34{
35 return gInitialized;
36}
37
38int
39CF_Socket_Initialize (void)
40{
41 int result = 0;
42
43#ifdef WIN32
44 WSADATA winsockData;
45 result = WSAStartup (MAKEWORD (2, 0), &winsockData);
46#endif
47 gInitialized = CF_TRUE;
48
49 if (result != 0)
50 return CF_ERROR_SOCKET_INITIALIZE;
51
52 return CF_OK;
53}
54
55int
56CF_Socket_Finalize (void)
57{
58 int result = 0;
59
60 if (!CF_Socket_IsInitialized ())
61 return CF_ERROR_SOCKET_NOT_INITIALIZED;
62
63#ifdef WIN32
64 result = WSACleanup ();
65#endif
66 if (result != 0)
67 return CF_ERROR_SOCKET_FINALIZE;
68
69 return CF_OK;
70}
71
72int
73CF_Socket_Close (const int sock)
74{
75 int result = 0;
76
77 CHECK_INVALID_SOCKET (sock);
78
79 result = close (sock);
80
81 if (result != 0)
82 return CF_ERROR_SOCKET_CLOSE;
83
84 return CF_OK;
85}
86
87int
88CF_Socket_SetOption (const int sock,
89 const int optname,
90 const void * optval,
91 const size_t optlen)
92{
93 int result = 0;
94
95 CHECK_INVALID_SOCKET (sock);
96
97 result = setsockopt (sock,
98 SOL_SOCKET,
99 optname,
100#ifdef _WIN32
101 (char *) optval,
102#else
103 optval,
104#endif
105 (socklen_t) optlen);
106 if (result < 0)
107 return CF_ERROR_SOCKET_SET_OPTION;
108
109 return CF_OK;
110}
111
112int
113CF_Socket_GetOption (const int sock,
114 const int optname,
115 void * optval,
116 size_t * optlen)
117{
118 int result = 0;
119
120 CHECK_INVALID_SOCKET (sock);
121
122 result = getsockopt (sock,
123 SOL_SOCKET,
124 optname,
125#ifdef _WIN32
126 (char *) optval,
127#else
128 optval,
129#endif
130 (socklen_t *) optlen);
131 if (result < 0)
132 return CF_ERROR_SOCKET_GET_OPTION;
133
134 return CF_OK;
135}
136
137int
138CF_Socket_SetTimeout (const int sock,
139 const int timeout)
140{
141 int result = 0;
142
143#ifdef _WIN32
144 int time_ms = timeout * 1000;
145#else
146 struct timeval timeval;
147 timeval.tv_sec = timeout;
148 timeval.tv_usec= 0;
149#endif
150
151 CHECK_INVALID_SOCKET (sock);
152
153 if (timeout < 0)
154 return CF_ERROR_SOCKET_INVALID_ARGS;
155
156 result = CF_Socket_SetOption (sock,
157 SO_RCVTIMEO,
158#ifdef _WIN32
159 &time_ms,
160 sizeof (time_ms));
161#else
162 &timeval,
163 sizeof (timeval));
164#endif
165 if (result < 0)
166 return CF_ERROR_SOCKET_SET_TIMEOUT;
167 /*----------------------------------------------------------------*/
168
169 return CF_OK;
170}
171
172int
173CF_Socket_Connect (const char * ip,
174 const unsigned short port)
175{
176 int result = 0;
177 int sock = 0;
178 struct sockaddr_in address;
179 struct hostent * hostEnt;
180
181 CHECK_SOCKET_INIT ();
182
183 sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
184 if (sock < 0)
185 return CF_ERROR_SOCKET_CREATE;
186
187 address.sin_family = AF_INET;
188 address.sin_port = htons (port);
189 address.sin_addr.s_addr = inet_addr (ip);
190
191 TRY
192 {
193 if (address.sin_addr.s_addr == (unsigned int)-1)
194 {
195 hostEnt = gethostbyname (ip);
196 if (hostEnt == NULL)
197 {
198 result = CF_ERROR_SOCKET_GET_HOST;
199 TRY_BREAK;
200 }
201
202 address.sin_family = (sa_family_t) hostEnt->h_addrtype;
203 memcpy (&(address.sin_addr.s_addr), hostEnt->h_addr, (size_t) hostEnt->h_length);
204 }
205
206 result = connect (sock, (struct sockaddr *) &address, sizeof (address));
207 if (result < 0)
208 {
209 result = CF_ERROR_SOCKET_CONNECT;
210 TRY_BREAK;
211 }
212 }
213 CATCH_IF (result < 0)
214 {
215 CF_Socket_Close (sock);
216 return result;
217 }
218
219 return CF_OK;
220}
221
222int
223CF_Socket_Server (const unsigned short port,
224 const int backlog)
225{
226 int result = 0;
227 int sock = 0;
228 struct sockaddr_in address;
229
230 CHECK_SOCKET_INIT ();
231
232 sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
233 if (sock < 0)
234 return CF_ERROR_SOCKET_CREATE;
235
236 address.sin_family = AF_INET;
237 address.sin_addr.s_addr = htonl (INADDR_ANY);
238 address.sin_port = htons (port);
239
240 TRY {
241 result = bind (sock, (struct sockaddr *) &address, sizeof (struct sockaddr));
242 if (result < 0)
243 {
244 result = CF_ERROR_SOCKET_BIND;
245 TRY_BREAK;
246 }
247
248 result = listen (sock, backlog);
249 if (result < 0)
250 {
251 result = CF_ERROR_SOCKET_LISTEN;
252 TRY_BREAK;
253 }
254 }
255 CATCH_IF (result < 0)
256 {
257 CF_Socket_Close (sock);
258 return result;
259 }
260
261 return sock;
262}
263
264int
265CF_Socket_Accept (const int sock,
266 void * address)
267{
268 int sockClient;
269 struct sockaddr_in remoteAddress;
270 socklen_t len = sizeof (remoteAddress);
271
272 CHECK_INVALID_SOCKET (sock);
273
274 sockClient = accept (sock, (struct sockaddr *) &remoteAddress, &len);
275 if (sockClient < 0)
276 return CF_ERROR_SOCKET_ACCEPT;
277
278 if (address != NULL)
279 memcpy ((void *) address, (void *) &remoteAddress, sizeof (struct sockaddr_in));
280
281 return sockClient;
282}
283
284int
285CF_Socket_Send (const int sock,
286 const void * buf,
287 const int len)
288{
289 int result = 0;
290
291 CHECK_INVALID_SOCKET (sock);
292
293 result = (int) send (sock, buf, (size_t) len, 0);
294 if (result != len)
295 return CF_ERROR_SOCKET_SEND;
296
297 return CF_OK;
298}
299
300int
301CF_Socket_Recv (const int sock,
302 void * buf,
303 const int len)
304{
305 int result = 0;
306
307 CHECK_INVALID_SOCKET (sock);
308
309 result = (int) recv (sock, buf, (size_t) len, 0);
310 if (result < 0)
311 return CF_ERROR_SOCKET_RECV;
312
313 return result;
314}
Note: See TracBrowser for help on using the repository browser.