< Summary

Information
Class: Ice.Internal.StreamSocket
Assembly: Ice
File(s): /_/csharp/src/Ice/Internal/StreamSocket.cs
Tag: 125_37167941578
Line coverage
81%
Covered lines: 164
Uncovered lines: 38
Coverable lines: 202
Total lines: 455
Line coverage: 81.1%
Branch coverage
77%
Covered branches: 71
Total branches: 92
Branch coverage: 77.1%
Method coverage
100%
Covered methods: 19
Fully covered methods: 8
Total methods: 19
Method coverage: 100%
Full method coverage: 42.1%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%22100%
.ctor(...)100%1172.73%
connect(...)93.75%161695.65%
fd()100%11100%
setBufferSize(...)100%11100%
read(...)100%66100%
write(...)37.5%27833.33%
startRead(...)0%2255.56%
finishRead(...)80%111078.95%
startWrite(...)62.5%11862.5%
finishWrite(...)78.57%181472.73%
close()100%11100%
destroy()100%11100%
ToString()100%11100%
read(...)80%101088.89%
write(...)83.33%6692.86%
ioCompleted(...)83.33%6683.33%
init(...)100%11100%
toState(...)75%4483.33%

File(s)

/_/csharp/src/Ice/Internal/StreamSocket.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using System.Diagnostics;
 4using System.Net;
 5using System.Net.Sockets;
 6
 7namespace Ice.Internal;
 8
 9#pragma warning disable CA1001 // _readEventArgs and _writeEventArgs are disposed by destroy.
 10internal sealed class StreamSocket
 11#pragma warning restore CA1001
 12{
 113    public StreamSocket(
 114        ProtocolInstance instance,
 115        NetworkProxy proxy,
 116        EndPoint addr,
 117        EndPoint sourceAddr,
 118        TcpBufSize bufSize)
 19    {
 120        _instance = instance;
 121        _proxy = proxy;
 122        _addr = addr;
 123        _sourceAddr = sourceAddr;
 124        _fd = Network.createSocket(false, (_proxy != null ? _proxy.getAddress() : _addr).AddressFamily);
 125        _state = StateNeedConnect;
 26
 127        init(bufSize);
 128    }
 29
 130    public StreamSocket(ProtocolInstance instance, Socket fd, TcpBufSize bufSize)
 31    {
 132        _instance = instance;
 133        _fd = fd;
 134        _state = StateConnected;
 35        try
 36        {
 137            _desc = Network.fdToString(_fd);
 138        }
 039        catch (System.Exception)
 40        {
 041            Network.closeSocketNoThrow(_fd);
 042            throw;
 43        }
 144        init(bufSize);
 145    }
 46
 47    public int connect(Buffer readBuffer, Buffer writeBuffer, ref bool moreData)
 48    {
 149        if (_state == StateNeedConnect)
 50        {
 151            _state = StateConnectPending;
 152            return SocketOperation.Connect;
 53        }
 154        else if (_state <= StateConnectPending)
 55        {
 156            if (_writeEventArgs.SocketError != SocketError.Success)
 57            {
 158                var ex = new System.Net.Sockets.SocketException((int)_writeEventArgs.SocketError);
 159                if (Network.connectionRefused(ex))
 60                {
 161                    throw new Ice.ConnectionRefusedException(_addr, ex);
 62                }
 63                else
 64                {
 065                    throw new Ice.ConnectFailedException(_addr, ex);
 66                }
 67            }
 168            _desc = Network.fdToString(_fd, _proxy, _addr);
 169            _state = _proxy != null ? StateProxyWrite : StateConnected;
 70        }
 71
 172        if (_state == StateProxyWrite)
 73        {
 174            _proxy.beginWrite(_addr, writeBuffer);
 175            return SocketOperation.Write;
 76        }
 177        else if (_state == StateProxyRead)
 78        {
 179            _proxy.beginRead(readBuffer);
 180            return SocketOperation.Read;
 81        }
 182        else if (_state == StateProxyConnected)
 83        {
 184            _proxy.finish(readBuffer, writeBuffer);
 85
 186            readBuffer.clear();
 187            writeBuffer.clear();
 88
 189            _state = StateConnected;
 90        }
 91
 92        Debug.Assert(_state == StateConnected);
 193        return SocketOperation.None;
 94    }
 95
 196    public Socket fd() => _fd;
 97
 198    public void setBufferSize(int rcvSize, int sndSize) => Network.setTcpBufSize(_fd, rcvSize, sndSize, _instance);
 99
 100    public int read(Buffer buf)
 101    {
 1102        if (_state == StateProxyRead)
 103        {
 104            while (true)
 105            {
 1106                int ret = read(buf.b);
 1107                if (ret == 0)
 108                {
 1109                    return SocketOperation.Read;
 110                }
 111
 1112                _state = toState(_proxy.endRead(buf));
 1113                if (_state != StateProxyRead)
 114                {
 1115                    return SocketOperation.None;
 116                }
 117            }
 118        }
 1119        read(buf.b);
 1120        return buf.b.hasRemaining() ? SocketOperation.Read : SocketOperation.None;
 121    }
 122
 123    public int write(Buffer buf)
 124    {
 1125        if (_state == StateProxyWrite)
 126        {
 127            while (true)
 128            {
 0129                int ret = write(buf.b);
 0130                if (ret == 0)
 131                {
 0132                    return SocketOperation.Write;
 133                }
 0134                _state = toState(_proxy.endWrite(buf));
 0135                if (_state != StateProxyWrite)
 136                {
 0137                    return SocketOperation.None;
 138                }
 139            }
 140        }
 1141        write(buf.b);
 1142        return buf.b.hasRemaining() ? SocketOperation.Write : SocketOperation.None;
 143    }
 144
 145    public bool startRead(Buffer buf, AsyncCallback callback, object state)
 146    {
 147        Debug.Assert(_fd != null && _readEventArgs != null);
 148
 149        try
 150        {
 1151            _readCallback = callback;
 1152            _readEventArgs.UserToken = state;
 1153            _readEventArgs.SetBuffer(buf.b.rawBytes(), buf.b.position(), buf.b.remaining());
 1154            return !_fd.ReceiveAsync(_readEventArgs);
 155        }
 0156        catch (System.Net.Sockets.SocketException ex)
 157        {
 0158            if (Network.connectionLost(ex))
 159            {
 0160                throw new Ice.ConnectionLostException(_addr, ex);
 161            }
 0162            throw new Ice.SocketException(ex);
 163        }
 1164    }
 165
 166    public void finishRead(Buffer buf)
 167    {
 1168        if (_fd == null) // Transceiver was closed
 169        {
 0170            return;
 171        }
 172
 173        Debug.Assert(_fd != null && _readEventArgs != null);
 174        try
 175        {
 1176            if (_readEventArgs.SocketError != SocketError.Success)
 177            {
 1178                throw new System.Net.Sockets.SocketException((int)_readEventArgs.SocketError);
 179            }
 1180            int ret = _readEventArgs.BytesTransferred;
 1181            _readEventArgs.SetBuffer(null, 0, 0);
 182
 1183            if (ret == 0)
 184            {
 1185                throw new Ice.ConnectionLostException(_addr);
 186            }
 187
 188            Debug.Assert(ret > 0);
 1189            buf.b.position(buf.b.position() + ret);
 190
 1191            if (_state == StateProxyRead)
 192            {
 1193                _state = toState(_proxy.endRead(buf));
 194            }
 1195        }
 1196        catch (System.Net.Sockets.SocketException ex)
 197        {
 1198            if (Network.connectionLost(ex))
 199            {
 1200                throw new Ice.ConnectionLostException(_addr, ex);
 201            }
 0202            throw new Ice.SocketException(ex);
 203        }
 0204        catch (ObjectDisposedException ex)
 205        {
 0206            throw new Ice.ConnectionLostException(_addr, ex);
 207        }
 1208    }
 209
 210    public bool startWrite(Buffer buf, AsyncCallback callback, object state, out bool messageWritten)
 211    {
 212        Debug.Assert(_fd != null && _writeEventArgs != null);
 1213        if (_state == StateConnectPending)
 214        {
 1215            messageWritten = false;
 1216            _writeCallback = callback;
 217            try
 218            {
 1219                EndPoint addr = _proxy != null ? _proxy.getAddress() : _addr;
 1220                if (_sourceAddr != null)
 221                {
 0222                    Network.doBind(_fd, _sourceAddr);
 223                }
 1224                _writeEventArgs.RemoteEndPoint = addr;
 1225                _writeEventArgs.UserToken = state;
 1226                return !_fd.ConnectAsync(_writeEventArgs);
 227            }
 0228            catch (System.Exception ex)
 229            {
 0230                throw new Ice.SocketException(ex);
 231            }
 232        }
 233
 234        try
 235        {
 1236            _writeCallback = callback;
 1237            _writeEventArgs.UserToken = state;
 1238            _writeEventArgs.SetBuffer(buf.b.rawBytes(), buf.b.position(), buf.b.remaining());
 1239            bool completedSynchronously = !_fd.SendAsync(_writeEventArgs);
 1240            messageWritten = true;
 1241            return completedSynchronously;
 242        }
 0243        catch (System.Net.Sockets.SocketException ex)
 244        {
 0245            if (Network.connectionLost(ex))
 246            {
 0247                throw new Ice.ConnectionLostException(_addr, ex);
 248            }
 0249            throw new Ice.SocketException(ex);
 250        }
 0251        catch (ObjectDisposedException ex)
 252        {
 0253            throw new Ice.ConnectionLostException(_addr, ex);
 254        }
 1255    }
 256
 257    public void finishWrite(Buffer buf)
 258    {
 1259        if (_fd == null) // Transceiver was closed
 260        {
 0261            buf.b.position(buf.b.limit()); // Assume all the data was sent for at-most-once semantics.
 0262            return;
 263        }
 264
 265        Debug.Assert(_fd != null && _writeEventArgs != null);
 266
 1267        if (_state < StateConnected && _state != StateProxyWrite)
 268        {
 1269            return;
 270        }
 271
 272        try
 273        {
 1274            if (_writeEventArgs.SocketError != SocketError.Success)
 275            {
 1276                throw new System.Net.Sockets.SocketException((int)_writeEventArgs.SocketError);
 277            }
 1278            int ret = _writeEventArgs.BytesTransferred;
 1279            _writeEventArgs.SetBuffer(null, 0, 0);
 1280            if (ret == 0)
 281            {
 0282                throw new Ice.ConnectionLostException(_addr);
 283            }
 284
 285            Debug.Assert(ret > 0);
 1286            buf.b.position(buf.b.position() + ret);
 287
 1288            if (_state == StateProxyWrite)
 289            {
 1290                _state = toState(_proxy.endWrite(buf));
 291            }
 1292        }
 1293        catch (System.Net.Sockets.SocketException ex)
 294        {
 1295            if (Network.connectionLost(ex))
 296            {
 1297                throw new Ice.ConnectionLostException(_addr, ex);
 298            }
 299
 0300            throw new Ice.SocketException(ex);
 301        }
 0302        catch (ObjectDisposedException ex)
 303        {
 0304            throw new Ice.ConnectionLostException(_addr, ex);
 305        }
 1306    }
 307
 308    public void close()
 309    {
 310        Debug.Assert(_fd != null);
 311        try
 312        {
 1313            Network.closeSocket(_fd);
 1314        }
 315        finally
 316        {
 1317            _fd = null;
 1318        }
 1319    }
 320
 321    public void destroy()
 322    {
 323        Debug.Assert(_readEventArgs != null && _writeEventArgs != null);
 1324        _readEventArgs.Dispose();
 1325        _writeEventArgs.Dispose();
 1326    }
 327
 1328    public override string ToString() => _desc;
 329
 330    private int read(ByteBuffer buf)
 331    {
 332        Debug.Assert(_fd != null);
 1333        int read = 0;
 1334        while (buf.hasRemaining())
 335        {
 336            try
 337            {
 1338                int ret = _fd.Receive(buf.rawBytes(), buf.position(), buf.remaining(), SocketFlags.None);
 1339                if (ret == 0)
 340                {
 1341                    throw new Ice.ConnectionLostException(_addr);
 342                }
 1343                read += ret;
 1344                buf.position(buf.position() + ret);
 1345            }
 1346            catch (System.Net.Sockets.SocketException ex)
 347            {
 1348                if (Network.wouldBlock(ex))
 349                {
 1350                    return read;
 351                }
 1352                else if (Network.interrupted(ex))
 353                {
 0354                    continue;
 355                }
 1356                else if (Network.connectionLost(ex))
 357                {
 1358                    throw new ConnectionLostException(_addr, ex);
 359                }
 360
 0361                throw new SocketException(ex);
 362            }
 363        }
 1364        return read;
 1365    }
 366
 367    private int write(ByteBuffer buf)
 368    {
 369        Debug.Assert(_fd != null);
 1370        int sent = 0;
 1371        while (buf.hasRemaining())
 372        {
 373            try
 374            {
 1375                int ret = _fd.Send(buf.rawBytes(), buf.position(), buf.remaining(), SocketFlags.None);
 376                Debug.Assert(ret > 0);
 377
 1378                sent += ret;
 1379                buf.position(buf.position() + ret);
 1380            }
 1381            catch (System.Net.Sockets.SocketException ex)
 382            {
 1383                if (Network.wouldBlock(ex))
 384                {
 1385                    return sent;
 386                }
 1387                else if (Network.connectionLost(ex))
 388                {
 1389                    throw new Ice.ConnectionLostException(_addr, ex);
 390                }
 0391                throw new Ice.SocketException(ex);
 392            }
 393        }
 1394        return sent;
 1395    }
 396
 397    private void ioCompleted(object sender, SocketAsyncEventArgs e)
 398    {
 1399        switch (e.LastOperation)
 400        {
 401            case SocketAsyncOperation.Receive:
 1402                _readCallback(e.UserToken);
 1403                break;
 404            case SocketAsyncOperation.Send:
 405            case SocketAsyncOperation.Connect:
 1406                _writeCallback(e.UserToken);
 1407                break;
 408            default:
 0409                throw new ArgumentException("The last operation completed on the socket was not a receive or send");
 410        }
 411    }
 412
 413    private void init(TcpBufSize bufSize)
 414    {
 1415        Network.setBlock(_fd, false);
 1416        Network.setTcpBufSize(_fd, bufSize.rcvSize, bufSize.sndSize, _instance);
 417
 1418        _readEventArgs = new SocketAsyncEventArgs();
 1419        _readEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(ioCompleted);
 420
 1421        _writeEventArgs = new SocketAsyncEventArgs();
 1422        _writeEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(ioCompleted);
 1423    }
 424
 425    private int toState(int operation)
 426    {
 1427        return operation switch
 1428        {
 1429            SocketOperation.Read => StateProxyRead,
 0430            SocketOperation.Write => StateProxyWrite,
 1431            _ => StateProxyConnected,
 1432        };
 433    }
 434
 435    private readonly ProtocolInstance _instance;
 436    private readonly NetworkProxy _proxy;
 437    private readonly EndPoint _addr;
 438    private readonly EndPoint _sourceAddr;
 439
 440    private Socket _fd;
 441    private int _state;
 442    private string _desc;
 443
 444    private SocketAsyncEventArgs _writeEventArgs;
 445    private SocketAsyncEventArgs _readEventArgs;
 446    private AsyncCallback _writeCallback;
 447    private AsyncCallback _readCallback;
 448
 449    private const int StateNeedConnect = 0;
 450    private const int StateConnectPending = 1;
 451    private const int StateProxyWrite = 2;
 452    private const int StateProxyRead = 3;
 453    private const int StateProxyConnected = 4;
 454    private const int StateConnected = 5;
 455}