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

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

#1 add doxygen prologue to .c file

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