77
120
cs_strcat(size, buffer, iService);
80
void SCSocket::throwError(const char *func, const char *file, int line, char *address, int err)
123
void CSSocket::throwError(const char *func, const char *file, int line, char *address, int err)
83
126
CSException::throwFileError(func, file, line, address, err);
93
136
throwError(func, file, line, address, err);
96
void SCSocket::setInternalOptions()
139
void CSSocket::setNoDelay()
100
143
if (setsockopt(iHandle, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)) == -1)
101
CSException::throwOSError(CS_CONTEXT, errno);
104
void SCSocket::openInternal()
106
iHandle = socket(AF_INET, SOCK_STREAM, 0);
144
CSException::throwOSError(CS_CONTEXT, SOCKET_ERRORNO);
147
void CSSocket::setNonBlocking()
150
unsigned long block = 1;
152
if (IOCTL_SOCKET(iHandle, FIONBIO, &block) != 0)
153
throwError(CS_CONTEXT, SOCKET_ERRORNO);
157
void CSSocket::setBlocking()
159
/* No timeout, set blocking: */
161
unsigned long block = 0;
163
if (IOCTL_SOCKET(iHandle, FIONBIO, &block) != 0)
164
throwError(CS_CONTEXT, SOCKET_ERRORNO);
168
void CSSocket::openInternal()
170
iHandle = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
107
171
if (iHandle == -1)
108
CSException::throwOSError(CS_CONTEXT, errno);
109
setInternalOptions();
172
CSException::throwOSError(CS_CONTEXT, SOCKET_ERRORNO);
177
void CSSocket::writeBlock(const void *data, size_t len)
183
out = send(iHandle, (const char *) data, len, 0);
186
int err = SOCKET_ERRORNO;
188
if (err == EWOULDBLOCK || err == EINTR)
190
throwError(CS_CONTEXT, err);
192
if ((size_t) out > len)
195
data = ((char *) data) + (size_t) out;
200
int CSSocket::timeoutRead(CSThread *self, void *buffer, size_t length)
204
uint64_t timeout = iTimeout * 1000;
206
start_time = CSTime::getTimeCurrentTicks();
209
in = recv(iHandle, (char *) buffer, length, 0);
211
if (SOCKET_ERRORNO == EWOULDBLOCK) {
214
struct timeval tv_timeout;
219
time_diff = CSTime::getTimeCurrentTicks() - start_time;
220
if (time_diff >= timeout) {
221
char address[CS_SOCKET_ADDRESS_SIZE];
223
formatAddress(CS_SOCKET_ADDRESS_SIZE, address);
224
CSException::throwExceptionf(CS_CONTEXT, CS_ERR_RECEIVE_TIMEOUT, "Receive timeout: %lu ms, on: %s", iTimeout, address);
227
/* Calculate how much time we can wait: */
228
time_diff = timeout - time_diff;
229
tv_timeout.tv_sec = (long)time_diff / 1000000;
230
tv_timeout.tv_usec = (long)time_diff % 1000000;
232
FD_SET(iHandle, &readfds);
233
in = select(iHandle+1, &readfds, NULL, NULL, &tv_timeout);
171
310
server.sin_port = (uint16_t) servp->s_port;
173
312
if (setsockopt(iHandle, SOL_SOCKET, SO_REUSEADDR, (char *) &flag, sizeof(int)) == -1)
174
CSException::throwOSError(CS_CONTEXT, errno);
313
CSException::throwOSError(CS_CONTEXT, SOCKET_ERRORNO);
176
315
if (bind(iHandle, (struct sockaddr *) &server, sizeof(server)) == -1)
177
CSException::throwOSError(CS_CONTEXT, errno);
316
CSException::throwOSError(CS_CONTEXT, SOCKET_ERRORNO);
179
318
if (listen(iHandle, SOMAXCONN) == -1)
180
CSException::throwOSError(CS_CONTEXT, errno);
319
CSException::throwOSError(CS_CONTEXT, SOCKET_ERRORNO);
211
350
iHost = (char *) cs_malloc(100);
212
351
iHandle = accept(listener_handle, (struct sockaddr *) &remote, &addrlen);
213
352
if (iHandle == -1)
214
throwError(CS_CONTEXT, address, errno);
353
throwError(CS_CONTEXT, address, SOCKET_ERRORNO);
216
355
cs_strcpy(100, iHost, inet_ntoa(remote.sin_addr));
217
356
iPort = ntohs(remote.sin_port);
219
setInternalOptions();
308
453
* So a return of zero means EOF!
311
in = recv(iHandle, data, len, 0);
457
in = timeoutRead(self, data, len);
459
in = recv(iHandle, (char *) data, len, 0);
312
460
self->interrupted();
314
462
/* Note, we actually ignore all errors on the socket.
315
463
* If no data was returned by the read so far, then
316
464
* the error will be considered EOF.
318
if (errno == EAGAIN || errno == EINTR)
466
int err = SOCKET_ERRORNO;
468
if (err == EWOULDBLOCK || err == EINTR)
470
throwError(CS_CONTEXT, err);
322
473
return_((size_t) in);
328
479
u_char buffer[1];
343
void SCSocket::write(const void *data, size_t len)
349
out = send(iHandle, data, len, 0);
354
if (err == EAGAIN || errno == EINTR)
356
throwError(CS_CONTEXT, err);
358
if ((size_t) out > len)
361
data = ((char *) data) + (size_t) out;
366
void SCSocket::write(char ch)
373
void SCSocket::flush()
494
void CSSocket::write(const void *data, size_t len)
496
#ifdef CS_USE_OUTPUT_BUFFER
497
if (len <= CS_MIN_WRITE_SIZE) {
498
if (iDataLen + len > CS_OUTPUT_BUFFER_SIZE) {
499
/* This is the amount of data that will still fit
502
size_t tfer = CS_OUTPUT_BUFFER_SIZE - iDataLen;
504
memcpy(iOutputBuffer + iDataLen, data, tfer);
507
memcpy(iOutputBuffer, ((char *) data) + tfer, len);
511
memcpy(iOutputBuffer + iDataLen, data, len);
516
/* If the block give is large enough, the
517
* writing directly from the block saves copying the
518
* data to the local output buffer buffer:
521
writeBlock(data, len);
524
writeBlock(data, len);
528
void CSSocket::write(char ch)
535
void CSSocket::flush()
537
#ifdef CS_USE_OUTPUT_BUFFER
540
if ((len = iDataLen)) {
542
/* Note: we discard the data to be written if an
545
writeBlock(iOutputBuffer, len);
550
const char *CSSocket::identify()
556
formatAddress(200, buffer);
557
iIdentity = cs_strdup(buffer);