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

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

#1 add test code for multi-threading, socket and multi-threaded logging

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