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

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

#1 로깅을 제외한 기본 코드 커밋

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