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

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

#1 add logging module (working), fix some bug code and move NAME_LENGTH definition

File size: 5.3 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
30CF_BOOL gInitialized = CF_FALSE;
31
32CF_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 CHECK_SOCKET_INIT ();
61
62#ifdef WIN32
63 result = WSACleanup ();
64#endif
65 if (result != 0)
66 return CF_ERROR_SOCKET_FINALIZE;
67
68 return CF_OK;
69}
70
71int
72CF_Socket_Close (const int sock)
73{
74 int result = 0;
75
76 CHECK_INVALID_SOCKET (sock);
77
78 result = close (sock);
79
80 if (result != 0)
81 return CF_ERROR_SOCKET_CLOSE;
82
83 return CF_OK;
84}
85
86int
87CF_Socket_SetOption (const int sock,
88 const int optname,
89 const void * optval,
90 const size_t optlen)
91{
92 int result = 0;
93
94 CHECK_INVALID_SOCKET (sock);
95
96 result = setsockopt (sock,
97 SOL_SOCKET,
98 optname,
99#ifdef _WIN32
100 (char *) optval,
101#else
102 optval,
103#endif
104 (socklen_t) optlen);
105 if (result < 0)
106 return CF_ERROR_SOCKET_SET_OPTION;
107
108 return CF_OK;
109}
110
111int
112CF_Socket_GetOption (const int sock,
113 const int optname,
114 void * optval,
115 size_t * optlen)
116{
117 int result = 0;
118
119 CHECK_INVALID_SOCKET (sock);
120
121 result = getsockopt (sock,
122 SOL_SOCKET,
123 optname,
124#ifdef _WIN32
125 (char *) optval,
126#else
127 optval,
128#endif
129 (socklen_t *) optlen);
130 if (result < 0)
131 return CF_ERROR_SOCKET_GET_OPTION;
132
133 return CF_OK;
134}
135
136int
137CF_Socket_SetTimeout (const int sock,
138 const int timeout)
139{
140 int result = 0;
141
142#ifdef _WIN32
143 int time_ms = timeout * 1000;
144#else
145 struct timeval timeval;
146 timeval.tv_sec = timeout;
147 timeval.tv_usec= 0;
148#endif
149
150 CHECK_INVALID_SOCKET (sock);
151
152 if (timeout < 0)
153 return CF_ERROR_SOCKET_INVALID_ARGS;
154
155 result = CF_Socket_SetOption (sock,
156 SO_RCVTIMEO,
157#ifdef _WIN32
158 &time_ms,
159 sizeof (time_ms));
160#else
161 &timeval,
162 sizeof (timeval));
163#endif
164 if (result < 0)
165 return CF_ERROR_SOCKET_SET_TIMEOUT;
166 /*----------------------------------------------------------------*/
167
168 return CF_OK;
169}
170
171int
172CF_Socket_Connect (const char * ip,
173 const unsigned short port)
174{
175 int result = 0;
176 int sock = 0;
177 struct sockaddr_in address;
178 struct hostent * hostEnt;
179
180 CHECK_SOCKET_INIT ();
181
182 sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
183 if (sock < 0)
184 return CF_ERROR_SOCKET_CREATE;
185
186 address.sin_family = AF_INET;
187 address.sin_port = htons (port);
188 address.sin_addr.s_addr = inet_addr (ip);
189
190 TRY
191 {
192 if (address.sin_addr.s_addr == (unsigned int)-1)
193 {
194 hostEnt = gethostbyname (ip);
195 if (hostEnt == NULL)
196 {
197 result = CF_ERROR_SOCKET_GET_HOST;
198 TRY_BREAK;
199 }
200
201 address.sin_family = (sa_family_t) hostEnt->h_addrtype;
202 memcpy (&(address.sin_addr.s_addr), hostEnt->h_addr, (size_t) hostEnt->h_length);
203 }
204
205 result = connect (sock, (struct sockaddr *) &address, sizeof (address));
206 if (result < 0)
207 {
208 result = CF_ERROR_SOCKET_CONNECT;
209 TRY_BREAK;
210 }
211 }
212 CATCH_IF (result < 0)
213 {
214 CF_Socket_Close (sock);
215 return result;
216 }
217
218 return CF_OK;
219}
220
221int
222CF_Socket_Server (const unsigned short port,
223 const int backlog)
224{
225 int result = 0;
226 int sock = 0;
227 struct sockaddr_in address;
228
229 CHECK_SOCKET_INIT ();
230
231 sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
232 if (sock < 0)
233 return CF_ERROR_SOCKET_CREATE;
234
235 address.sin_family = AF_INET;
236 address.sin_addr.s_addr = htonl (INADDR_ANY);
237 address.sin_port = htons (port);
238
239 TRY {
240 result = bind (sock, (struct sockaddr *) &address, sizeof (struct sockaddr));
241 if (result < 0)
242 {
243 result = CF_ERROR_SOCKET_BIND;
244 TRY_BREAK;
245 }
246
247 result = listen (sock, backlog);
248 if (result < 0)
249 {
250 result = CF_ERROR_SOCKET_LISTEN;
251 TRY_BREAK;
252 }
253 }
254 CATCH_IF (result < 0)
255 {
256 CF_Socket_Close (sock);
257 return result;
258 }
259
260 return sock;
261}
262
263int
264CF_Socket_Accept (const int sock,
265 void * address)
266{
267 int sockClient;
268 struct sockaddr_in remoteAddress;
269 socklen_t len = sizeof (remoteAddress);
270
271 CHECK_INVALID_SOCKET (sock);
272
273 sockClient = accept (sock, (struct sockaddr *) &remoteAddress, &len);
274 if (sockClient < 0)
275 return CF_ERROR_SOCKET_ACCEPT;
276
277 if (address != NULL)
278 memcpy ((void *) address, (void *) &remoteAddress, sizeof (struct sockaddr_in));
279
280 return sockClient;
281}
282
283int
284CF_Socket_Send (const int sock,
285 const void * buf,
286 const int len)
287{
288 int result = 0;
289
290 CHECK_INVALID_SOCKET (sock);
291
292 result = (int) send (sock, buf, (size_t) len, 0);
293 if (result != len)
294 return CF_ERROR_SOCKET_SEND;
295
296 return CF_OK;
297}
298
299int
300CF_Socket_Recv (const int sock,
301 void * buf,
302 const int len)
303{
304 int result = 0;
305
306 CHECK_INVALID_SOCKET (sock);
307
308 result = (int) recv (sock, buf, (size_t) len, 0);
309 if (result < 0)
310 return CF_ERROR_SOCKET_RECV;
311
312 return result;
313}
Note: See TracBrowser for help on using the repository browser.