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