source: cheroxy/trunk/src/CRXSocket.cpp@ 59

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

#1 add SetOption in CRXSocket

File size: 10.5 KB
Line 
1/**
2 * CRXSocket.cpp
3 */
4#include "CRXSocket.h"
5
6#include <string.h>
7
8#ifdef _WIN32
9# pragma comment (lib, "ws2_32.lib")
10# define close(__socket) closesocket(__socket)
11#endif
12
13bool CRXSocket::mInitialized = false;
14
15CRXSocket::CRXSocket (int aSocket)
16 : mSocket (aSocket)
17{
18 /*----------------------------------------------------------------*/
19 CRXSocket::Initialize ();
20
21 memset ((void *)&mAddress, 0x0, sizeof (struct sockaddr_in));
22 /*----------------------------------------------------------------*/
23}
24
25CRXSocket::~CRXSocket (void)
26{
27 /*----------------------------------------------------------------*/
28 Close ();
29 /*----------------------------------------------------------------*/
30}
31
32void
33CRXSocket::Attach (int aSocket)
34{
35 /*----------------------------------------------------------------*/
36 mSocket = aSocket;
37 /*----------------------------------------------------------------*/
38}
39
40int
41CRXSocket::Detach (void)
42{
43 int aSocket = mSocket;
44
45 /*----------------------------------------------------------------*/
46 mSocket = 0;
47
48 /*----------------------------------------------------------------*/
49 return aSocket;
50}
51
52void
53CRXSocket::Close (void)
54{
55 /*----------------------------------------------------------------*/
56 if (mSocket <= 0)
57 return ;
58
59 close (mSocket);
60 mSocket = 0;
61 /*----------------------------------------------------------------*/
62}
63
64CRXSocket::operator int (void) const
65{
66 /*----------------------------------------------------------------*/
67 /*----------------------------------------------------------------*/
68 return mSocket;
69}
70
71CRXSocket &
72CRXSocket::operator = (int aSocket)
73{
74 /*----------------------------------------------------------------*/
75 Attach (aSocket);
76 /*----------------------------------------------------------------*/
77 return *this;
78}
79
80int
81CRXSocket::SetOption (const int aOptName,
82 const void * aOptVal,
83 const size_t aOptLen)
84{
85 int aResult = 0;
86 /*----------------------------------------------------------------*/
87 aResult = setsockopt (mSocket,
88 SOL_SOCKET,
89 aOptName,
90#ifdef _WIN32
91 (char *) aOptVal,
92#else
93 aOptVal,
94#endif
95 (socklen_t) aOptLen);
96 if (aResult < 0)
97 {
98 aResult = ERROR_TCPSOCKET_FAILED_TO_SET_SOCKOPT;
99 CRX_ERROR_SET (aResult, "Failed to set socket option.");
100 }
101 /*----------------------------------------------------------------*/
102
103 return aResult;
104}
105
106int
107CRXSocket::SetTimeout (const int aTimeout)
108{
109 int aResult = 0;
110
111#ifndef _WIN32
112 struct timeval aTimeVal;
113 aTimeVal.tv_sec = aTimeout;
114 aTimeVal.tv_usec= 0;
115#else
116 int aTimeMilliSec = aTimeout * 1000;
117#endif
118
119 /*----------------------------------------------------------------*/
120 if (!IsReady ())
121 return ERROR_TCPSOCKET_NOT_READY;
122
123 if (aTimeout == TCPSOCKET_NO_TIMEOUT)
124 return 0;
125
126 aResult = SetOption (SO_RCVTIMEO,
127#ifdef _WIN32
128 &aTimeMilliSec,
129 sizeof (aTimeMilliSec));
130#else
131 &aTimeVal,
132 sizeof (aTimeVal));
133#endif
134 if (aResult < 0)
135 {
136 aResult = ERROR_TCPSOCKET_FAILED_TO_SET_TIMEOUT;
137 CRX_ERROR_SET (aResult, "Failed to set socket tieout.");
138 }
139 /*----------------------------------------------------------------*/
140
141 return aResult;
142}
143
144int
145CRXSocket::Initialize (void)
146{
147 int aResult = 0;
148
149 /*----------------------------------------------------------------*/
150 if (CRXSocket::IsInitialized ())
151 return aResult;
152
153#ifdef WIN32
154 WSADATA aWinSockData;
155
156 aResult = WSAStartup (MAKEWORD (2, 0), &aWinSockData);
157 if (aResult != 0)
158 {
159 aResult = ERROR_TCPSOCKET_FAILED_TO_INITIALIZE;
160 return aResult;
161 }
162#endif
163
164 mInitialized = true;
165
166 /*----------------------------------------------------------------*/
167 return aResult;
168}
169
170void
171CRXSocket::Finalize (void)
172{
173 /*----------------------------------------------------------------*/
174#ifdef WIN32
175 WSACleanup ();
176#endif
177 /*----------------------------------------------------------------*/
178}
179
180bool
181CRXSocket::IsInitialized (void)
182{
183 /*----------------------------------------------------------------*/
184 /*----------------------------------------------------------------*/
185 return mInitialized;
186}
187
188bool
189CRXSocket::IsReady (void) const
190{
191 /*----------------------------------------------------------------*/
192 /*----------------------------------------------------------------*/
193 return IsInitialized () && IsCreated ();
194}
195
196bool
197CRXSocket::IsCreated (void) const
198{
199 /*----------------------------------------------------------------*/
200 /*----------------------------------------------------------------*/
201 return mSocket > 0 ? true : false;
202}
203
204int
205CRXSocket::CreateSocket (void)
206{
207 int aResult = -1;
208
209 /*----------------------------------------------------------------*/
210 if (!IsInitialized () || IsCreated ())
211 {
212 aResult = ERROR_TCPSOCKET_ALREADY_IN_USE;
213 CRX_ERROR_SET (aResult, "Already in use.");
214 return aResult;
215 }
216
217 aResult = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
218 if (aResult < 0)
219 {
220 aResult = ERROR_TCPSOCKET_FAILED_TO_CREATE_SOCKET;
221 CRX_ERROR_SET (aResult, "Failed to create socket(%d).", GetSystemErrorCode ());
222 return aResult;
223 }
224
225 mSocket = aResult;
226
227 /*----------------------------------------------------------------*/
228 return aResult;
229}
230
231int
232CRXSocket::Connect (const std::string aUrl,
233 const unsigned short aPort,
234 const int aTimeout)
235{
236 int aResult = -1;
237 struct hostent * aHostEnt;
238 struct linger aLinger;
239
240 /*----------------------------------------------------------------*/
241 aResult = CreateSocket ();
242 if (aResult < 0)
243 {
244 aResult = ERROR_TCPSOCKET_FAILED_TO_CREATE_SOCKET;
245 CRX_ERROR_SET (aResult, "Failed to create socket(%d).", GetSystemErrorCode ());
246 return aResult;
247 }
248
249 mAddress.sin_family = AF_INET;
250 mAddress.sin_port = htons (aPort);
251 mAddress.sin_addr.s_addr = inet_addr (aUrl.c_str ());
252
253 if (mAddress.sin_addr.s_addr == (unsigned int)-1)
254 {
255 aHostEnt = gethostbyname (aUrl.c_str ());
256 if (aHostEnt == NULL)
257 {
258 aResult = ERROR_TCPSOCKET_FAILED_TO_GET_HOSTNAME;
259 CRX_ERROR_SET (aResult, "Failed to get hostname.");
260 return aResult;
261 }
262 mAddress.sin_family = aHostEnt->h_addrtype;
263 memcpy (&(mAddress.sin_addr.s_addr), aHostEnt->h_addr, aHostEnt->h_length);
264 }
265
266 aLinger.l_onoff = 1;
267 aLinger.l_linger = 0;
268 aResult = SetOption (SO_LINGER,
269 &aLinger,
270 sizeof (aLinger));
271 if (aResult < 0)
272 {
273 aResult = ERROR_TCPSOCKET_FAILED_TO_SET_SOCKOPT;
274 CRX_ERROR_SET (aResult, "Failed to set socket option (linger).");
275 }
276
277 aResult = SetTimeout (aTimeout);
278 if (aResult < 0)
279 {
280 aResult = ERROR_TCPSOCKET_FAILED_TO_SET_TIMEOUT;
281 CRX_ERROR_SET (aResult, "Failed to set timeout (%d).", GetSystemErrorCode ());
282 return aResult;
283 }
284
285 aResult = connect (mSocket, (struct sockaddr*) &mAddress, sizeof (mAddress));
286 if (aResult < 0)
287 {
288 aResult = ERROR_TCPSOCKET_FAILED_TO_CONNECT;
289 CRX_ERROR_SET (aResult, "Failed to connect (%d).", GetSystemErrorCode ());
290 }
291 /*----------------------------------------------------------------*/
292
293 return aResult;
294}
295
296int
297CRXSocket::CreateServer (const unsigned short aPort,
298 const int aBacklog,
299 struct sockaddr_in * aAddress)
300{
301 int aResult = -1;
302
303 int aReuseAddress = 1;
304
305 /*----------------------------------------------------------------*/
306 aResult = CreateSocket ();
307 if (aResult < 0)
308 {
309 aResult = ERROR_TCPSOCKET_FAILED_TO_CREATE_SOCKET;
310 CRX_ERROR_SET (aResult, "Failed to create socket(%d).", GetSystemErrorCode ());
311 return aResult;
312 }
313
314 aResult = SetOption (SO_REUSEADDR,
315 &aReuseAddress,
316 sizeof (aReuseAddress));
317 if (aResult < 0)
318 {
319 aResult = ERROR_TCPSOCKET_FAILED_TO_SET_SOCKOPT;
320 CRX_ERROR_SET (aResult, "Failed to set socket option (reuseaddr).");
321 }
322
323 mAddress.sin_family = AF_INET;
324 mAddress.sin_addr.s_addr= htonl (INADDR_ANY);
325 mAddress.sin_port = htons (aPort);
326
327 aResult = bind (mSocket, (struct sockaddr *)&mAddress, sizeof (struct sockaddr));
328 if (aResult < 0)
329 {
330 aResult = ERROR_TCPSOCKET_FAILED_TO_BIND;
331 CRX_ERROR_SET (aResult, "Failed to bind(%d).", GetSystemErrorCode ());
332 return aResult;
333 }
334
335 aResult = listen (mSocket, aBacklog);
336 if (aResult < 0)
337 {
338 aResult = ERROR_TCPSOCKET_FAILED_TO_LISTEN;
339 CRX_ERROR_SET (aResult, "Failed to listen(%d).", GetSystemErrorCode ());
340 return aResult;
341 }
342
343 if (aAddress != NULL)
344 {
345 memset ((void *)aAddress, 0x0, sizeof (struct sockaddr_in));
346 memcpy ((void *)aAddress, (void *)&mAddress, sizeof (struct sockaddr_in));
347 }
348
349 /*----------------------------------------------------------------*/
350 return aResult;
351}
352
353int
354CRXSocket::Accept (struct sockaddr_in * aRemoteAddress,
355 int * aAddressLength)
356{
357 int aResult = -1;
358
359 struct sockaddr_in aAddress;
360 socklen_t aLength = sizeof (aAddress);
361
362 /*----------------------------------------------------------------*/
363 if (!IsReady ())
364 return ERROR_TCPSOCKET_NOT_READY;
365
366 aResult = accept (mSocket, (struct sockaddr *) &aAddress, &aLength);
367 if (aResult < 0)
368 {
369 aResult = ERROR_TCPSOCKET_FAILED_TO_ACCEPT;
370 CRX_ERROR_SET (aResult, "Failed to accept(%d).", GetSystemErrorCode ());
371 return aResult;
372 }
373
374 if (aRemoteAddress != NULL)
375 {
376 memset ((void *)aRemoteAddress, 0x0, sizeof (struct sockaddr_in));
377 memcpy ((void *)aRemoteAddress, (void *)&aAddress, sizeof (struct sockaddr_in));
378 }
379
380 if (aAddressLength != NULL)
381 *aAddressLength = aLength;
382
383 /*----------------------------------------------------------------*/
384 return aResult;
385}
386
387int
388CRXSocket::Send (const char * aBuffer,
389 int aSize)
390{
391 int aResult = -1;
392
393 /*----------------------------------------------------------------*/
394 if (!IsReady ())
395 return ERROR_TCPSOCKET_NOT_READY;
396
397 aResult = send (mSocket, aBuffer, aSize, 0);
398 if (aResult != aSize)
399 {
400 aResult = ERROR_TCPSOCKET_FAILED_TO_SEND;
401 CRX_ERROR_SET (aResult, "Failed to send(%d).", GetSystemErrorCode ());
402 return aResult;
403 }
404
405 /*----------------------------------------------------------------*/
406 return aResult;
407}
408
409int
410CRXSocket::Receive (char * aBuffer,
411 int aSize)
412{
413 int aResult = -1;
414
415 /*----------------------------------------------------------------*/
416 if (!IsReady ())
417 return ERROR_TCPSOCKET_NOT_READY;
418
419 aResult = recv (mSocket, aBuffer, aSize, 0);
420 if (aResult < 0)
421 {
422 aResult = ERROR_TCPSOCKET_FAILED_TO_RECEIVE;
423 CRX_ERROR_SET (aResult, "Failed to receive(%d).", GetSystemErrorCode ());
424 return aResult;
425 }
426
427 /*----------------------------------------------------------------*/
428 return aResult;
429}
Note: See TracBrowser for help on using the repository browser.