15
15
* You should have received a copy of the GNU General Public License
16
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
19
* Original author: Paul McCullagh (H&G2JCtL)
20
20
* Continued development: Barry Leslie
120
77
cs_strcat(size, buffer, iService);
123
void CSSocket::throwError(const char *func, const char *file, int line, char *address, int err)
80
void SCSocket::throwError(const char *func, const char *file, int line, char *address, int err)
126
83
CSException::throwFileError(func, file, line, address, err);
136
93
throwError(func, file, line, address, err);
139
void CSSocket::setNoDelay()
96
void SCSocket::setInternalOptions()
143
100
if (setsockopt(iHandle, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)) == -1)
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);
101
CSException::throwOSError(CS_CONTEXT, errno);
104
void SCSocket::openInternal()
106
iHandle = socket(AF_INET, SOCK_STREAM, 0);
171
107
if (iHandle == -1)
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);
108
CSException::throwOSError(CS_CONTEXT, errno);
109
setInternalOptions();
310
171
server.sin_port = (uint16_t) servp->s_port;
312
173
if (setsockopt(iHandle, SOL_SOCKET, SO_REUSEADDR, (char *) &flag, sizeof(int)) == -1)
313
CSException::throwOSError(CS_CONTEXT, SOCKET_ERRORNO);
174
CSException::throwOSError(CS_CONTEXT, errno);
315
176
if (bind(iHandle, (struct sockaddr *) &server, sizeof(server)) == -1)
316
CSException::throwOSError(CS_CONTEXT, SOCKET_ERRORNO);
177
CSException::throwOSError(CS_CONTEXT, errno);
318
179
if (listen(iHandle, SOMAXCONN) == -1)
319
CSException::throwOSError(CS_CONTEXT, SOCKET_ERRORNO);
180
CSException::throwOSError(CS_CONTEXT, errno);
350
211
iHost = (char *) cs_malloc(100);
351
212
iHandle = accept(listener_handle, (struct sockaddr *) &remote, &addrlen);
352
213
if (iHandle == -1)
353
throwError(CS_CONTEXT, address, SOCKET_ERRORNO);
214
throwError(CS_CONTEXT, address, errno);
355
216
cs_strcpy(100, iHost, inet_ntoa(remote.sin_addr));
356
217
iPort = ntohs(remote.sin_port);
219
setInternalOptions();
453
308
* So a return of zero means EOF!
457
in = timeoutRead(self, data, len);
459
in = recv(iHandle, (char *) data, len, 0);
311
in = recv(iHandle, data, len, 0);
460
312
self->interrupted();
462
314
/* Note, we actually ignore all errors on the socket.
463
315
* If no data was returned by the read so far, then
464
316
* the error will be considered EOF.
466
int err = SOCKET_ERRORNO;
468
if (err == EWOULDBLOCK || err == EINTR)
318
if (errno == EAGAIN || errno == EINTR)
470
throwError(CS_CONTEXT, err);
473
322
return_((size_t) in);
479
328
u_char buffer[1];
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);
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()