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

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

#1 more mutex interface and add debugging code to check connection port number

File size: 9.4 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::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 sizeof (aTimeMilliSec));
106#else
107 &aTimeVal,
108 (socklen_t) sizeof (aTimeVal));
109#endif
110 if (aResult < 0)
111 {
112 aResult = ERROR_TCPSOCKET_FAILED_TO_SETSOCKOPT;
113 CRX_ERROR_SET (aResult, "Failed to set socket option.");
114 }
115 /*----------------------------------------------------------------*/
116
117 return aResult;
118}
119
120int
121CRXSocket::Initialize (void)
122{
123 int aResult = 0;
124
125 /*----------------------------------------------------------------*/
126 if (CRXSocket::IsInitialized ())
127 return aResult;
128
129#ifdef WIN32
130 WSADATA aWinSockData;
131
132 aResult = WSAStartup (MAKEWORD (2, 0), &aWinSockData);
133 if (aResult != 0)
134 {
135 aResult = ERROR_TCPSOCKET_FAILED_TO_INITIALIZE;
136 return aResult;
137 }
138#endif
139
140 mInitialized = true;
141
142 /*----------------------------------------------------------------*/
143 return aResult;
144}
145
146void
147CRXSocket::Finalize (void)
148{
149 /*----------------------------------------------------------------*/
150#ifdef WIN32
151 WSACleanup ();
152#endif
153 /*----------------------------------------------------------------*/
154}
155
156bool
157CRXSocket::IsInitialized (void)
158{
159 /*----------------------------------------------------------------*/
160 /*----------------------------------------------------------------*/
161 return mInitialized;
162}
163
164bool
165CRXSocket::IsReady (void) const
166{
167 /*----------------------------------------------------------------*/
168 /*----------------------------------------------------------------*/
169 return IsInitialized () && IsCreated ();
170}
171
172bool
173CRXSocket::IsCreated (void) const
174{
175 /*----------------------------------------------------------------*/
176 /*----------------------------------------------------------------*/
177 return mSocket > 0 ? true : false;
178}
179
180int
181CRXSocket::CreateSocket (void)
182{
183 int aResult = -1;
184
185 /*----------------------------------------------------------------*/
186 if (!IsInitialized () || IsCreated ())
187 {
188 aResult = ERROR_TCPSOCKET_ALREADY_IN_USE;
189 CRX_ERROR_SET (aResult, "Already in use.");
190 return aResult;
191 }
192
193 aResult = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
194 if (aResult < 0)
195 {
196 aResult = ERROR_TCPSOCKET_FAILED_TO_CREATE_SOCKET;
197 CRX_ERROR_SET (aResult, "Failed to create socket(%d).", GetSystemErrorCode ());
198 return aResult;
199 }
200
201 mSocket = aResult;
202
203 /*----------------------------------------------------------------*/
204 return aResult;
205}
206
207int
208CRXSocket::Connect (const std::string aUrl,
209 const unsigned short aPort,
210 const int aTimeout)
211{
212 int aResult = -1;
213 struct hostent * aHostEnt;
214
215 /*----------------------------------------------------------------*/
216 aResult = CreateSocket ();
217 if (aResult < 0)
218 {
219 aResult = ERROR_TCPSOCKET_FAILED_TO_CREATE_SOCKET;
220 CRX_ERROR_SET (aResult, "Failed to create socket(%d).", GetSystemErrorCode ());
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 {
233 aResult = ERROR_TCPSOCKET_FAILED_TO_GET_HOSTNAME;
234 CRX_ERROR_SET (aResult, "Failed to get hostname.");
235 return aResult;
236 }
237 mAddress.sin_family = aHostEnt->h_addrtype;
238 memcpy (&(mAddress.sin_addr.s_addr), aHostEnt->h_addr, aHostEnt->h_length);
239 }
240
241 aResult = SetTimeout (aTimeout);
242 if (aResult < 0)
243 {
244 aResult = ERROR_TCPSOCKET_FAILED_TO_SETSOCKOPT;
245 CRX_ERROR_SET (aResult, "Failed to set timeout (%d).", GetSystemErrorCode ());
246 return aResult;
247 }
248
249 aResult = connect (mSocket, (struct sockaddr*) &mAddress, sizeof (mAddress));
250 if (aResult < 0)
251 {
252 aResult = ERROR_TCPSOCKET_FAILED_TO_CONNECT;
253 CRX_ERROR_SET (aResult, "Failed to connect (%d).", GetSystemErrorCode ());
254 }
255
256 /*----------------------------------------------------------------*/
257 return aResult;
258}
259
260int
261CRXSocket::CreateServer (const unsigned short aPort,
262 const int aBacklog,
263 struct sockaddr_in * aAddress)
264{
265 int aResult = -1;
266
267 /*----------------------------------------------------------------*/
268 aResult = CreateSocket ();
269 if (aResult < 0)
270 {
271 aResult = ERROR_TCPSOCKET_FAILED_TO_CREATE_SOCKET;
272 CRX_ERROR_SET (aResult, "Failed to create socket(%d).", GetSystemErrorCode ());
273 return aResult;
274 }
275
276 mAddress.sin_family = AF_INET;
277 mAddress.sin_addr.s_addr= htonl (INADDR_ANY);
278 mAddress.sin_port = htons (aPort);
279
280 aResult = bind (mSocket, (struct sockaddr *)&mAddress, sizeof (struct sockaddr));
281 if (aResult < 0)
282 {
283 aResult = ERROR_TCPSOCKET_FAILED_TO_BIND;
284 CRX_ERROR_SET (aResult, "Failed to bind(%d).", GetSystemErrorCode ());
285 return aResult;
286 }
287
288 aResult = listen (mSocket, aBacklog);
289 if (aResult < 0)
290 {
291 aResult = ERROR_TCPSOCKET_FAILED_TO_LISTEN;
292 CRX_ERROR_SET (aResult, "Failed to listen(%d).", GetSystemErrorCode ());
293 return aResult;
294 }
295
296 if (aAddress != NULL)
297 {
298 memset ((void *)aAddress, 0x0, sizeof (struct sockaddr_in));
299 memcpy ((void *)aAddress, (void *)&mAddress, sizeof (struct sockaddr_in));
300 }
301
302 /*----------------------------------------------------------------*/
303 return aResult;
304}
305
306int
307CRXSocket::Accept (struct sockaddr_in * aRemoteAddress,
308 int * aAddressLength)
309{
310 int aResult = -1;
311
312 struct sockaddr_in aAddress;
313 socklen_t aLength = sizeof (aAddress);
314
315 /*----------------------------------------------------------------*/
316 if (!IsReady ())
317 return ERROR_TCPSOCKET_NOT_READY;
318
319 aResult = accept (mSocket, (struct sockaddr *) &aAddress, &aLength);
320 if (aResult < 0)
321 {
322 aResult = ERROR_TCPSOCKET_FAILED_TO_ACCEPT;
323 CRX_ERROR_SET (aResult, "Failed to accept(%d).", GetSystemErrorCode ());
324 return aResult;
325 }
326
327 if (aRemoteAddress != NULL)
328 {
329 memset ((void *)aRemoteAddress, 0x0, sizeof (struct sockaddr_in));
330 memcpy ((void *)aRemoteAddress, (void *)&aAddress, sizeof (struct sockaddr_in));
331 }
332
333 if (aAddressLength != NULL)
334 *aAddressLength = aLength;
335
336 /*----------------------------------------------------------------*/
337 return aResult;
338}
339
340int
341CRXSocket::Send (const char * aBuffer,
342 int aSize)
343{
344 int aResult = -1;
345
346 /*----------------------------------------------------------------*/
347 if (!IsReady ())
348 return ERROR_TCPSOCKET_NOT_READY;
349
350 aResult = send (mSocket, aBuffer, aSize, 0);
351 if (aResult != aSize)
352 {
353 aResult = ERROR_TCPSOCKET_FAILED_TO_SEND;
354 CRX_ERROR_SET (aResult, "Failed to send(%d).", GetSystemErrorCode ());
355 return aResult;
356 }
357
358 /*----------------------------------------------------------------*/
359 return aResult;
360}
361
362int
363CRXSocket::Receive (char * aBuffer,
364 int aSize)
365{
366 int aResult = -1;
367
368 /*----------------------------------------------------------------*/
369 if (!IsReady ())
370 return ERROR_TCPSOCKET_NOT_READY;
371
372 aResult = recv (mSocket, aBuffer, aSize, 0);
373 if (aResult < 0)
374 {
375 aResult = ERROR_TCPSOCKET_FAILED_TO_RECEIVE;
376 CRX_ERROR_SET (aResult, "Failed to receive(%d).", GetSystemErrorCode ());
377 return aResult;
378 }
379
380 /*----------------------------------------------------------------*/
381 return aResult;
382}
Note: See TracBrowser for help on using the repository browser.