20
21
using namespace Ice;
21
22
using namespace IceInternal;
24
IceInternal::TcpTransceiver::fd()
26
assert(_fd != INVALID_SOCKET);
25
IceInternal::TcpTransceiver::getNativeInfo()
32
IceInternal::TcpTransceiver::getAsyncInfo(SocketOperation status)
36
case SocketOperationRead:
38
case SocketOperationWrite:
48
IceInternal::TcpTransceiver::initialize()
50
if(_state == StateNeedConnect)
52
_state = StateConnectPending;
53
return SocketOperationConnect;
55
else if(_state <= StateConnectPending)
62
doFinishConnectAsync(_fd, _write);
64
_state = StateConnected;
65
_desc = fdToString(_fd);
67
catch(const Ice::LocalException& ex)
69
if(_traceLevels->network >= 2)
71
Trace out(_logger, _traceLevels->networkCat);
72
out << "failed to establish tcp connection\n" << _desc << "\n" << ex;
77
if(_traceLevels->network >= 1)
79
Trace out(_logger, _traceLevels->networkCat);
80
out << "tcp connection established\n" << _desc;
83
assert(_state == StateConnected);
84
return SocketOperationNone;
31
88
IceInternal::TcpTransceiver::close()
33
if(_traceLevels->network >= 1)
90
if(_state == StateConnected && _traceLevels->network >= 1)
35
92
Trace out(_logger, _traceLevels->networkCat);
36
93
out << "closing tcp connection\n" << toString();
55
112
// Its impossible for the packetSize to be more than an Int.
56
113
int packetSize = static_cast<int>(buf.b.end() - buf.i);
60
117
// Limit packet size to avoid performance problems on WIN32
62
if(packetSize > _maxPacketSize)
119
if(_maxSendPacketSize > 0 && packetSize > _maxSendPacketSize)
64
packetSize = _maxPacketSize;
121
packetSize = _maxSendPacketSize;
68
125
while(buf.i != buf.b.end())
70
127
assert(_fd != INVALID_SOCKET);
71
129
ssize_t ret = ::send(_fd, reinterpret_cast<const char*>(&*buf.i), packetSize, 0);
75
132
ConnectionLostException ex(__FILE__, __LINE__);
216
if(packetSize > buf.b.end() - buf.i)
218
packetSize = static_cast<int>(buf.b.end() - buf.i);
273
packetSize = static_cast<int>(buf.b.end() - buf.i);
281
IceInternal::TcpTransceiver::startWrite(Buffer& buf)
283
if(_state < StateConnected)
285
doConnectAsync(_fd, _connectAddr, _write);
286
_desc = fdToString(_fd);
290
assert(!buf.b.empty() && buf.i != buf.b.end());
292
int packetSize = static_cast<int>(buf.b.end() - buf.i);
293
if(_maxSendPacketSize > 0 && packetSize > _maxSendPacketSize)
295
packetSize = _maxSendPacketSize;
298
_write.buf.len = packetSize;
299
_write.buf.buf = reinterpret_cast<char*>(&*buf.i);
300
int err = WSASend(_fd, &_write.buf, 1, &_write.count, 0, &_write, NULL);
301
if(err == SOCKET_ERROR)
307
ConnectionLostException ex(__FILE__, __LINE__);
308
ex.error = getSocketErrno();
313
SocketException ex(__FILE__, __LINE__);
314
ex.error = getSocketErrno();
319
return packetSize == static_cast<int>(buf.b.end() - buf.i);
323
IceInternal::TcpTransceiver::finishWrite(Buffer& buf)
325
if(_state < StateConnected)
330
if(_write.count == SOCKET_ERROR)
332
WSASetLastError(_write.error);
335
ConnectionLostException ex(__FILE__, __LINE__);
336
ex.error = getSocketErrno();
341
SocketException ex(__FILE__, __LINE__);
342
ex.error = getSocketErrno();
347
if(_traceLevels->network >= 3)
349
int packetSize = static_cast<int>(buf.b.end() - buf.i);
350
if(_maxSendPacketSize > 0 && packetSize > _maxSendPacketSize)
352
packetSize = _maxSendPacketSize;
354
Trace out(_logger, _traceLevels->networkCat);
355
out << "sent " << _write.count << " of " << packetSize << " bytes via tcp\n" << toString();
360
_stats->bytesSent(type(), _write.count);
363
buf.i += _write.count;
367
IceInternal::TcpTransceiver::startRead(Buffer& buf)
369
int packetSize = static_cast<int>(buf.b.end() - buf.i);
370
if(_maxReceivePacketSize > 0 && packetSize > _maxReceivePacketSize)
372
packetSize = _maxReceivePacketSize;
375
assert(!buf.b.empty() && buf.i != buf.b.end());
377
_read.buf.len = packetSize;
378
_read.buf.buf = reinterpret_cast<char*>(&*buf.i);
379
int err = WSARecv(_fd, &_read.buf, 1, &_read.count, &_read.flags, &_read, NULL);
380
if(err == SOCKET_ERROR)
386
ConnectionLostException ex(__FILE__, __LINE__);
387
ex.error = getSocketErrno();
392
SocketException ex(__FILE__, __LINE__);
393
ex.error = getSocketErrno();
401
IceInternal::TcpTransceiver::finishRead(Buffer& buf)
403
if(_read.count == SOCKET_ERROR)
405
WSASetLastError(_read.error);
408
ConnectionLostException ex(__FILE__, __LINE__);
409
ex.error = getSocketErrno();
414
SocketException ex(__FILE__, __LINE__);
415
ex.error = getSocketErrno();
419
else if(_read.count == 0)
421
ConnectionLostException ex(__FILE__, __LINE__);
426
if(_traceLevels->network >= 3)
428
int packetSize = static_cast<int>(buf.b.end() - buf.i);
429
if(_maxReceivePacketSize > 0 && packetSize > _maxReceivePacketSize)
431
packetSize = _maxReceivePacketSize;
433
Trace out(_logger, _traceLevels->networkCat);
434
out << "received " << _read.count << " of " << packetSize << " bytes via tcp\n" << toString();
439
_stats->bytesReceived(type(), static_cast<Int>(_read.count));
442
buf.i += _read.count;
226
447
IceInternal::TcpTransceiver::type() const
238
IceInternal::TcpTransceiver::initialize()
458
Ice::ConnectionInfoPtr
459
IceInternal::TcpTransceiver::getInfo() const
240
if(_state == StateNeedConnect)
242
_state = StateConnectPending;
245
else if(_state <= StateConnectPending)
249
doFinishConnect(_fd);
250
_state = StateConnected;
251
_desc = fdToString(_fd);
253
catch(const Ice::LocalException& ex)
255
if(_traceLevels->network >= 2)
257
Trace out(_logger, _traceLevels->networkCat);
258
out << "failed to establish tcp connection\n" << _desc << "\n" << ex;
263
if(_traceLevels->network >= 1)
265
Trace out(_logger, _traceLevels->networkCat);
266
out << "tcp connection established\n" << _desc;
269
assert(_state == StateConnected);
461
assert(_fd != INVALID_SOCKET);
462
Ice::TCPConnectionInfoPtr info = new Ice::TCPConnectionInfo();
463
fdToAddressAndPort(_fd, info->localAddress, info->localPort, info->remoteAddress, info->remotePort);
276
470
if(buf.b.size() > messageSizeMax)
278
throw MemoryLimitException(__FILE__, __LINE__);
472
Ex::throwMemoryLimitException(__FILE__, __LINE__, buf.b.size(), messageSizeMax);
282
476
IceInternal::TcpTransceiver::TcpTransceiver(const InstancePtr& instance, SOCKET fd, bool connected) :
283
478
_traceLevels(instance->traceLevels()),
284
479
_logger(instance->initializationData().logger),
285
480
_stats(instance->initializationData().stats),
287
481
_state(connected ? StateConnected : StateNeedConnect),
288
_desc(fdToString(_fd))
482
_desc(connected ? fdToString(_fd) : string())
484
, _read(SocketOperationRead),
485
_write(SocketOperationWrite)
488
setBlock(_fd, false);
489
setTcpBufSize(_fd, instance->initializationData().properties, _logger);
292
493
// On Windows, limiting the buffer size is important to prevent
293
494
// poor throughput performances when transfering large amount of
294
495
// data. See Microsoft KB article KB823764.
296
_maxPacketSize = IceInternal::getSendBufferSize(_fd) / 2;
297
if(_maxPacketSize < 512)
497
_maxSendPacketSize = IceInternal::getSendBufferSize(fd) / 2;
498
if(_maxSendPacketSize < 512)
500
_maxSendPacketSize = 0;
503
_maxReceivePacketSize = IceInternal::getRecvBufferSize(fd);
504
if(_maxReceivePacketSize < 512)
506
_maxReceivePacketSize = 0;