Rev 1122 | Rev 1203 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed
| Rev 1122 | Rev 1124 | ||
|---|---|---|---|
| Line 75... | Line 75... | ||
| 75 | loop = receiveData(); |
75 | loop = receiveData(); |
| 76 | } |
76 | } |
| 77 | } |
77 | } |
| 78 | catch (SocketException *e) |
78 | catch (SocketException *e) |
| 79 | { |
79 | { |
| - | 80 | cout << "DEBUG: socket got an exception: " << e->getDescription() << endl; |
|
| 80 | // Something bad happend and we can not continue |
81 | // Something bad happend and we can not continue |
| 81 | eventAdd(SocketEvent::TYPE_CONNECTION_DIED, e->getDescription()); |
82 | eventAdd(SocketEvent::TYPE_CONNECTION_DIED, e->getDescription()); |
| 82 | } |
83 | } |
| 83 | 84 | ||
| 84 | // Clean up socket if we would want to restart |
85 | // Clean up socket if we would want to restart |
| Line 88... | Line 89... | ||
| 88 | bool AsyncSocket::receiveData() |
89 | bool AsyncSocket::receiveData() |
| 89 | { |
90 | { |
| 90 | char buffer[MAXBUFFER + 1]; |
91 | char buffer[MAXBUFFER + 1]; |
| 91 | memset(buffer, 0, MAXBUFFER + 1); |
92 | memset(buffer, 0, MAXBUFFER + 1); |
| 92 | 93 | ||
| - | 94 | //cout << "recv start" << endl; |
|
| 93 | int status = ::recv(mySocket, buffer, MAXBUFFER, 0); |
95 | int status = ::recv(mySocket, buffer, MAXBUFFER, 0); |
| - | 96 | //cout << "recv end" << endl; |
|
| 94 | 97 | ||
| 95 | if (status == -1) |
98 | if (status == -1) |
| 96 | { |
99 | { |
| 97 | switch (errno) |
100 | switch (errno) |
| 98 | { |
101 | { |
| 99 | case EAGAIN: |
102 | case EAGAIN: |
| Line 111... | Line 114... | ||
| 111 | case EINTR: |
114 | case EINTR: |
| 112 | throw new SocketException("The receive was interrupted by delivery of a signal before any data were available; see signal(7)."); |
115 | throw new SocketException("The receive was interrupted by delivery of a signal before any data were available; see signal(7)."); |
| 113 | 116 | ||
| 114 | case EINVAL: |
117 | case EINVAL: |
| 115 | throw new SocketException("Invalid argument passed."); |
118 | throw new SocketException("Invalid argument passed."); |
| 116 | 119 | ||
| 117 | case ENOMEM: |
120 | case ENOMEM: |
| 118 | throw new SocketException("Could not allocate memory for recvmsg()."); |
121 | throw new SocketException("Could not allocate memory for recvmsg()."); |
| 119 | 122 | ||
| 120 | case ENOTCONN: |
123 | case ENOTCONN: |
| 121 | throw new SocketException("The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and accept(2))."); |
124 | throw new SocketException("The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and accept(2))."); |
| 122 | 125 | ||
| 123 | case ENOTSOCK: |
126 | case ENOTSOCK: |
| 124 | throw new SocketException("The argument s does not refer to a socket."); |
127 | throw new SocketException("The argument s does not refer to a socket."); |
| 125 | 128 | ||
| 126 | case ECONNRESET: |
129 | case ECONNRESET: |
| 127 | eventAdd(SocketEvent::TYPE_CONNECTION_RESET); |
130 | eventAdd(SocketEvent::TYPE_CONNECTION_RESET); |
| 128 | 131 | ||
| 129 | // If we have automatic reconnect we want to start it now |
132 | // If we have automatic reconnect we want to start it now |
| 130 | if (myReconnectTimeout == 0) |
133 | if (myReconnectTimeout == 0) |
| 131 | { |
134 | { |
| 132 | reconnectLoop(); |
135 | reconnectLoop(); |
| 133 | } |
136 | } |
| 134 | else |
137 | else |
| 135 | { |
138 | { |
| 136 | // Otherwise we would like to end the main loop |
139 | // Otherwise we would like to end the main loop |
| 137 | return false; |
140 | return false; |
| 138 | } |
141 | } |
| 139 | break; |
142 | break; |
| 140 | 143 | ||
| 141 | default: |
144 | default: |
| 142 | throw new SocketException("Unknow exception: " + itos(errno)); |
145 | throw new SocketException("Unknow exception: " + itos(errno)); |
| 143 | break; |
146 | break; |
| 144 | } |
147 | } |
| 145 | } |
148 | } |
| Line 218... | Line 221... | ||
| 218 | { |
221 | { |
| 219 | create(); |
222 | create(); |
| 220 | 223 | ||
| 221 | myAddressStruct.sin_family = AF_INET; |
224 | myAddressStruct.sin_family = AF_INET; |
| 222 | myAddressStruct.sin_addr.s_addr = INADDR_ANY; |
225 | myAddressStruct.sin_addr.s_addr = INADDR_ANY; |
| 223 | myAddressStruct.sin_port = htons(myPort); |
226 | myAddressStruct.sin_port = htons(myPort); |
| 224 | 227 | ||
| 225 | int status = ::bind(mySocket, (struct sockaddr *)&myAddressStruct, sizeof(myAddressStruct)); |
228 | int status = ::bind(mySocket, (struct sockaddr *)&myAddressStruct, sizeof(myAddressStruct)); |
| 226 | 229 | ||
| 227 | if (status == -1) |
230 | if (status == -1) |
| 228 | { |
231 | { |
| 229 | silentClose(); |
232 | silentClose(); |
| 230 | switch (errno) |
233 | switch (errno) |
| 231 | { |
234 | { |
| 232 | case EACCES: |
235 | case EACCES: |
| 233 | throw new SocketException("The address is protected, and the user is not the superuser."); |
236 | throw new SocketException("The address is protected, and the user is not the superuser."); |
| 234 | 237 | ||
| 235 | case EADDRINUSE: |
238 | case EADDRINUSE: |
| 236 | throw new SocketException("The given address is already in use."); |
239 | throw new SocketException("The given address is already in use."); |
| 237 | 240 | ||
| Line 250... | Line 253... | ||
| 250 | case EADDRNOTAVAIL: |
253 | case EADDRNOTAVAIL: |
| 251 | throw new SocketException("A nonexistent interface was requested or the requested address was not local."); |
254 | throw new SocketException("A nonexistent interface was requested or the requested address was not local."); |
| 252 | 255 | ||
| 253 | case EFAULT: |
256 | case EFAULT: |
| 254 | throw new SocketException("addr points outside the user's accessible address space."); |
257 | throw new SocketException("addr points outside the user's accessible address space."); |
| 255 | 258 | ||
| 256 | //case EINVAL: |
259 | //case EINVAL: |
| 257 | //throw new SocketException("The addrlen is wrong, or the socket was not in the AF_UNIX family."); |
260 | //throw new SocketException("The addrlen is wrong, or the socket was not in the AF_UNIX family."); |
| 258 | 261 | ||
| 259 | case ELOOP: |
262 | case ELOOP: |
| 260 | throw new SocketException("Too many symbolic links were encountered in resolving addr."); |
263 | throw new SocketException("Too many symbolic links were encountered in resolving addr."); |
| 261 | 264 | ||
| 262 | case ENAMETOOLONG: |
265 | case ENAMETOOLONG: |
| 263 | throw new SocketException("addr is too long."); |
266 | throw new SocketException("addr is too long."); |
| 264 | 267 | ||
| 265 | case ENOENT: |
268 | case ENOENT: |
| 266 | throw new SocketException("The file does not exist."); |
269 | throw new SocketException("The file does not exist."); |
| 267 | 270 | ||
| 268 | case ENOMEM: |
271 | case ENOMEM: |
| 269 | throw new SocketException("Insufficient kernel memory was available."); |
272 | throw new SocketException("Insufficient kernel memory was available."); |
| 270 | 273 | ||
| 271 | case ENOTDIR: |
274 | case ENOTDIR: |
| 272 | throw new SocketException("A component of the path prefix is not a directory."); |
275 | throw new SocketException("A component of the path prefix is not a directory."); |
| 273 | 276 | ||
| 274 | case EROFS: |
277 | case EROFS: |
| 275 | throw new SocketException("The socket inode would reside on a read-only file system."); |
278 | throw new SocketException("The socket inode would reside on a read-only file system."); |
| 276 | 279 | ||
| 277 | default: |
280 | default: |
| 278 | throw new SocketException("Unknow exception: " + itos(errno)); |
281 | throw new SocketException("Unknow exception: " + itos(errno)); |
| 279 | break; |
282 | break; |
| 280 | } |
283 | } |
| 281 | } |
284 | } |
| 282 | 285 | ||
| 283 | status = ::listen(mySocket, MAXCONNECTIONS); |
286 | status = ::listen(mySocket, MAXCONNECTIONS); |
| 284 | 287 | ||
| 285 | if (status == -1) |
288 | if (status == -1) |
| 286 | { |
289 | { |
| 287 | silentClose(); |
290 | silentClose(); |
| 288 | switch (errno) |
291 | switch (errno) |
| 289 | { |
292 | { |
| Line 296... | Line 299... | ||
| 296 | case ENOTSOCK: |
299 | case ENOTSOCK: |
| 297 | throw new SocketException("The argument sockfd is not a socket."); |
300 | throw new SocketException("The argument sockfd is not a socket."); |
| 298 | 301 | ||
| 299 | case EOPNOTSUPP: |
302 | case EOPNOTSUPP: |
| 300 | throw new SocketException("The socket is not of a type that supports the listen() operation."); |
303 | throw new SocketException("The socket is not of a type that supports the listen() operation."); |
| 301 | 304 | ||
| 302 | default: |
305 | default: |
| 303 | throw new SocketException("Unknow exception: " + itos(errno)); |
306 | throw new SocketException("Unknow exception: " + itos(errno)); |
| 304 | break; |
307 | break; |
| 305 | } |
308 | } |
| 306 | } |
309 | } |
| 307 | } |
310 | } |
| 308 | 311 | ||
| 309 | bool AsyncSocket::accept(AsyncSocket* newSocket) |
312 | bool AsyncSocket::accept(AsyncSocket* newSocket) |
| 310 | { |
313 | { |
| 311 | int addr_length = sizeof(myAddressStruct); |
314 | int addr_length = sizeof(myAddressStruct); |
| 312 | int socket = ::accept(mySocket, (sockaddr*)&myAddressStruct, (socklen_t*)&addr_length); |
315 | int socket = ::accept(mySocket, (sockaddr*)&myAddressStruct, (socklen_t*)&addr_length); |
| 313 | 316 | ||
| 314 | if (socket > 0) |
317 | if (socket > 0) |
| 315 | { |
318 | { |
| 316 | newSocket->setSocket(socket); |
319 | newSocket->setSocket(socket); |
| 317 | return true; |
320 | return true; |
| 318 | } |
321 | } |
| 319 | 322 | ||
| 320 | return false; |
323 | return false; |
| 321 | } |
324 | } |
| 322 | 325 | ||
| 323 | void AsyncSocket::connect() |
326 | void AsyncSocket::connect() |
| 324 | { |
327 | { |
| 325 | eventAdd(SocketEvent::TYPE_CONNECTING); |
328 | eventAdd(SocketEvent::TYPE_CONNECTING); |
| 326 | 329 | ||
| 327 | create(); |
330 | create(); |
| 328 | 331 | ||
| 329 | memset(&myAddressStruct, 0, sizeof(myAddressStruct)); |
332 | memset(&myAddressStruct, 0, sizeof(myAddressStruct)); |
| 330 | 333 | ||
| 331 | myAddressStruct.sin_family = AF_INET; |
334 | myAddressStruct.sin_family = AF_INET; |
| 332 | myAddressStruct.sin_port = htons(myPort); |
335 | myAddressStruct.sin_port = htons(myPort); |
| 333 | 336 | ||
| 334 | struct hostent *hptr = gethostbyname(myAddress.c_str()); |
337 | struct hostent *hptr = gethostbyname(myAddress.c_str()); |
| 335 | if (hptr == NULL) |
338 | if (hptr == NULL) |
| 336 | { |
339 | { |
| 337 | silentClose(); |
340 | silentClose(); |
| 338 | throw new SocketException("Connect: Could not resolv ip address"); |
341 | throw new SocketException("Connect: Could not resolv ip address"); |
| 339 | } |
342 | } |
| 340 | 343 | ||
| 341 | memcpy(&myAddressStruct.sin_addr, hptr->h_addr, hptr->h_length); |
344 | memcpy(&myAddressStruct.sin_addr, hptr->h_addr, hptr->h_length); |
| 342 | 345 | ||
| 343 | int status = ::connect(mySocket, (sockaddr*)&myAddressStruct, sizeof(myAddressStruct)); |
346 | int status = ::connect(mySocket, (sockaddr*)&myAddressStruct, sizeof(myAddressStruct)); |
| 344 | 347 | ||
| 345 | if (status == -1) |
348 | if (status == -1) |
| 346 | { |
349 | { |
| 347 | silentClose(); |
350 | silentClose(); |
| Line 365... | Line 368... | ||
| 365 | case EALREADY: |
368 | case EALREADY: |
| 366 | throw new SocketException("The socket is non-blocking and a previous connection attempt has not yet been completed."); |
369 | throw new SocketException("The socket is non-blocking and a previous connection attempt has not yet been completed."); |
| 367 | 370 | ||
| 368 | case EBADF: |
371 | case EBADF: |
| 369 | throw new SocketException("The file descriptor is not a valid index in the descriptor table."); |
372 | throw new SocketException("The file descriptor is not a valid index in the descriptor table."); |
| 370 | 373 | ||
| 371 | case ECONNREFUSED: |
374 | case ECONNREFUSED: |
| 372 | throw new SocketException("No-one listening on the remote address."); |
375 | throw new SocketException("No-one listening on the remote address."); |
| 373 | 376 | ||
| 374 | case EFAULT: |
377 | case EFAULT: |
| 375 | throw new SocketException("The socket structure address is outside the user's address space."); |
378 | throw new SocketException("The socket structure address is outside the user's address space."); |
| Line 402... | Line 405... | ||
| 402 | 405 | ||
| 403 | void AsyncSocket::sendData(string data) |
406 | void AsyncSocket::sendData(string data) |
| 404 | { |
407 | { |
| 405 | mySendMutex.lock(); |
408 | mySendMutex.lock(); |
| 406 | 409 | ||
| 407 | int status = ::send(mySocket, data.c_str(), data.size(), |
410 | int status = ::send(mySocket, data.c_str(), data.size(), MSG_NOSIGNAL); |
| 408 | //Logger::getInstance().add("Sent: \"" + data + "\" status was " + itos(status) + "\n"); |
411 | //Logger::getInstance().add("Sent: \"" + data + "\" status was " + itos(status) + "\n"); |
| 409 | mySendMutex.unlock(); |
412 | mySendMutex.unlock(); |
| 410 | 413 | ||
| 411 | //Logger &log = Logger::getInstance(); |
414 | //Logger &log = Logger::getInstance(); |
| 412 | //log.add("Sent: \"" + data + "\" status was " + itos(status) + "\n"); |
415 | //log.add("Sent: \"" + data + "\" status was " + itos(status) + "\n"); |
| Line 459... | Line 462... | ||
| 459 | 462 | ||
| 460 | case EOPNOTSUPP: |
463 | case EOPNOTSUPP: |
| 461 | throw new SocketException("Some bit in the flags argument is inappropriate for the socket type."); |
464 | throw new SocketException("Some bit in the flags argument is inappropriate for the socket type."); |
| 462 | 465 | ||
| 463 | case EPIPE: |
466 | case EPIPE: |
| - | 467 | close(); |
|
| - | 468 | stop(); |
|
| 464 |
|
469 | //throw new SocketException("The local end has been shut down on a connection oriented socket. In this case the process will also receive a SIGPIPE unless MSG_NOSIGNAL is set."); |
| - | 470 | break; |
|
| 465 | 471 | ||
| 466 | default: |
472 | default: |
| 467 | throw new SocketException("Unknow exception: " + itos(errno)); |
473 | throw new SocketException("Unknow exception: " + itos(errno)); |
| 468 | } |
474 | } |
| 469 | } |
475 | } |