source: cheroxy/trunk/src/CRXSocket.cpp

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

#1 change function to create socket

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