Beispiel #1
0
 public bool Listen(int port, int maxConnections, INetDriverCallbacks callbacks)
 {
     Assert.IsNull(clientSend);
     Assert.IsNull(serverSend);
     serverSend = new LocalGameNetDriverConnection(this, callbacks);
     return(true);
 }
Beispiel #2
0
    public bool Listen(int port, int maxConnections, INetDriverCallbacks callbacks)
    {
        Assert.IsTrue(hostSocketID == -1);

        hostCallbacks = callbacks;

        ConnectionConfig config = new ConnectionConfig();

        config.DisconnectTimeout               = 4000;
        config.PacketSize                      = 1372;
        config.MaxSentMessageQueueSize         = ushort.MaxValue;
        config.MaxCombinedReliableMessageCount = ushort.MaxValue;
        config.MaxCombinedReliableMessageSize  = 1024;
        config.AcksType = ConnectionAcksType.Acks64;

        hostReliableChannelID   = config.AddChannel(QosType.ReliableSequenced);
        hostUnreliableChannelID = config.AddChannel(QosType.Unreliable);
        hostSocketID            = NetworkTransport.AddHost(new HostTopology(config, maxConnections), port);
        if (hostSocketID == -1)
        {
            hostUnreliableChannelID = 0;
            hostReliableChannelID   = 0;
        }
        else
        {
            Debug.Log("UNET: started server.");
        }
        return(hostSocketID != -1);
    }
Beispiel #3
0
    public UnityNetDriverConnection(IntHashtable <UnityNetDriverConnection> connections, UnityNetDriver driver, INetDriverCallbacks callbacks, int socketId, int connectionId, int reliableChannel, int unreliableChannel)
    {
        _netDriver         = driver;
        this.callbacks     = callbacks;
        _socketID          = socketId;
        _connectionID      = connectionId;
        _unreliableChannel = unreliableChannel;
        _reliableChannel   = reliableChannel;
        this.connections   = connections;

        int    port;
        ulong  network;
        ushort node;
        byte   error;

        NetworkTransport.GetConnectionInfo(socketId, connectionId, out port, out network, out node, out error);

        byte[] ip = System.BitConverter.GetBytes(network);
        if (network == ulong.MaxValue)           // loopback
        {
            ip[0] = 127;
            ip[1] = 0;
            ip[2] = 0;
            ip[3] = 0;
        }
        _id = string.Format("{0}.{1}.{2}.{3}:{4}", ip[0], ip[1], ip[2], ip[3], port);
    }
    public void Dispose()
    {
        _serverCallbacks = null;
        _clientCallbacks = null;

        for (int i = 0; i < 2; ++i)
        {
            if (_serverSock[i] != null)
            {
                try {
                    _serverSock[i].Close();
                } catch (Exception) { }
                _serverSock[i] = null;
            }

            var connections = new List <SocketNetDriverConnection>(_tcpConnections.Values);
            foreach (var c in connections)
            {
                c.Dispose();
            }

            _tcpConnections.Clear();
            _udpConnections.Clear();
        }
    }
    public bool Listen(int port, int maxConnections, INetDriverCallbacks callbacks)
    {
        _serverCallbacks = callbacks;

        var endPoint = new IPEndPoint(IPAddress.Any, port);

        _serverSock[0] = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        _serverSock[1] = new Socket(endPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

        try {
            _serverSock[0].Bind(endPoint);
            _serverSock[0].Listen(maxConnections);

            _serverSock[1].Bind(endPoint);
            _serverSock[1].ReceiveBufferSize = World.MAX_UNRELIABLE_MESSAGE_SIZE * 4;
            _serverSock[1].DisableICMPUnreachablePortError();

            _serverSock[0].Blocking = false;
            //_serverSock[1].Blocking = false;
        } catch (Exception e) {
            Debug.LogException(e);
            return(false);
        }

        return(true);
    }
Beispiel #6
0
 public bool Connect(string address, int port, INetDriverCallbacks callbacks)
 {
     Assert.IsNotNull(serverSend);
     Assert.IsNull(clientSend);
     clientSend = new LocalGameNetDriverConnection(this, callbacks);
     serverSend.connectPending = true;
     return(true);
 }
Beispiel #7
0
 public void Dispose()
 {
     if (callbacks != null)
     {
         callbacks.OnDisconnect(this);
         callbacks = null;
         netDriver.Disconnect(this);
     }
 }
Beispiel #8
0
 public void Dispose()
 {
     if (callbacks != null)
     {
         byte error;
         NetworkTransport.Disconnect(_socketID, _connectionID, out error);
         callbacks.OnDisconnect(this);
         callbacks = null;
         if (connections != null)
         {
             _netDriver.RemoveConnection(connections, _connectionID);
         }
     }
 }
    public bool Connect(string address, int port, INetDriverCallbacks callbacks)
    {
        if (address == "localhost")
        {
            address = "127.0.0.1";
        }

        var serverIP = GetIPAddressFromString(address);

        if (serverIP == null)
        {
            Debug.LogError("Could not resolve " + address);
            return(false);
        }

        _clientCallbacks = callbacks;

        var serverEndPoint = new IPEndPoint(serverIP, port);

        var clientSocks = new Socket[2];

        clientSocks[0] = new Socket(serverEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        clientSocks[1] = new Socket(serverEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

        try {
            clientSocks[0].NoDelay           = true;
            clientSocks[0].SendTimeout       = 500;
            clientSocks[0].ReceiveBufferSize = World.MAX_RELIABLE_MESSAGE_SIZE;

            clientSocks[1].SendBufferSize    = World.MAX_UNRELIABLE_MESSAGE_SIZE * 4;
            clientSocks[1].ReceiveBufferSize = World.MAX_UNRELIABLE_MESSAGE_SIZE * 4;
            clientSocks[1].DisableICMPUnreachablePortError();

            Debug.Log("Connecting to " + serverEndPoint.Address.ToString());

            clientSocks[0].Connect(serverEndPoint);
            clientSocks[1].Bind(new IPEndPoint(IPAddress.Any, 0));

            Debug.Log("Connected to " + serverEndPoint.Address.ToString());

            _serverConnection             = new SocketNetDriverConnection(this, clientSocks, -1);
            _serverConnection.udpEndpoint = clientSocks[0].RemoteEndPoint;
        } catch (Exception e) {
            Debug.LogException(e);
            return(false);
        }

        return(true);
    }
Beispiel #10
0
    public void Dispose()
    {
        var tempConnections = hostConnections;

        hostConnections = new IntHashtable <UnityNetDriverConnection>();

        foreach (var conn in tempConnections.Values)
        {
            conn.connections = null;
            conn.Dispose();
        }

        tempConnections   = clientConnections;
        clientConnections = new IntHashtable <UnityNetDriverConnection>();

        foreach (var conn in tempConnections.Values)
        {
            conn.connections = null;
            conn.Dispose();
        }

        byte error;

        if (hostSocketID != -1)
        {
            NetworkTransport.DisconnectNetworkHost(hostSocketID, out error);
            hostSocketID            = -1;
            hostReliableChannelID   = 0;
            hostUnreliableChannelID = 0;
        }
        if (clientSocketID != -1)
        {
            NetworkTransport.DisconnectNetworkHost(clientSocketID, out error);
            clientSocketID            = -1;
            clientReliableChannelID   = 0;
            clientUnreliableChannelID = 0;
        }

        hostCallbacks   = null;
        clientCallbacks = null;
    }
Beispiel #11
0
    public bool Connect(string address, int port, INetDriverCallbacks callbacks)
    {
        Assert.IsTrue(clientSocketID == -1);

        if (address == "localhost")
        {
            address = "127.0.0.1";
        }

        clientCallbacks = callbacks;

        ConnectionConfig config = new ConnectionConfig();

        config.DisconnectTimeout               = 4000;
        config.PacketSize                      = 1372;
        config.MaxSentMessageQueueSize         = ushort.MaxValue;
        config.MaxCombinedReliableMessageCount = ushort.MaxValue;
        config.MaxCombinedReliableMessageSize  = 1024;
        config.AcksType = ConnectionAcksType.Acks64;

        clientReliableChannelID   = config.AddChannel(QosType.ReliableSequenced);
        clientUnreliableChannelID = config.AddChannel(QosType.Unreliable);
        clientSocketID            = NetworkTransport.AddHost(new HostTopology(config, 1));

        byte error;

        NetworkTransport.Connect(clientSocketID, address, port, 0, out error);
        if (error == (byte)NetworkError.Ok)
        {
            Debug.Log("UNET: connecting to server (" + address + ":" + port + ")");
        }
        else
        {
            Debug.Log("UNET: failed to connect to server (" + address + ":" + port + "), error (" + ((NetworkError)error).ToString() + ")");
        }

        return(error == (byte)NetworkError.Ok);
    }
Beispiel #12
0
    UnityNetDriverConnection CreateConnection(IntHashtable <UnityNetDriverConnection> connections, INetDriverCallbacks callbacks, int socketID, int connectionID, int reliableChannelID, int unreliableChannelID)
    {
        var hashCode = connectionID.GetHashCode();

        if (connections.Contains(hashCode))
        {
            throw new System.IO.IOException("Duplicate connection id! " + connectionID);
        }
        var conn = new UnityNetDriverConnection(connections, this, callbacks, socketID, connectionID, reliableChannelID, unreliableChannelID);

        connections[hashCode] = conn;
        return(conn);
    }
Beispiel #13
0
    void TickSocket(IntHashtable <UnityNetDriverConnection> connections, INetDriverCallbacks callbacks, int socketID, int reliableChannelID, int unreliableChannelID, byte[] recvBuffer, ref NetIOMetrics reliableChannelMetrics, ref NetIOMetrics unreliableChannelMetrics)
    {
        int  connectionID;
        int  recvSize;
        int  channelID;
        byte error;

        while (true)
        {
            NetworkEventType eventType = NetworkTransport.ReceiveFromHost(socketID, out connectionID, out channelID, recvBuffer, recvBuffer.Length, out recvSize, out error);
            switch (eventType)
            {
            case NetworkEventType.ConnectEvent: {
                var conn = GetConnection(connections, connectionID);
                if (conn == null)
                {
                    conn = CreateConnection(connections, callbacks, socketID, connectionID, reliableChannelID, unreliableChannelID);
                }
                callbacks.OnConnect(conn);
            } break;

            case NetworkEventType.DisconnectEvent: {
                var conn = GetConnection(connections, connectionID);
                if (conn == null)
                {
                    conn = CreateConnection(connections, callbacks, socketID, connectionID, reliableChannelID, unreliableChannelID);
                }
                conn.callbacks = null;
                callbacks.OnDisconnect(conn);
                RemoveConnection(connections, connectionID);
            } break;

            case NetworkEventType.DataEvent: {
                var conn = GetConnection(connections, connectionID);
                if (conn != null)
                {
                    if (channelID == reliableChannelID)
                    {
                        reliableChannelMetrics.bytesRecv += recvSize;
                        ++reliableChannelMetrics.numPacketsRecv;
                    }
                    else
                    {
                        unreliableChannelMetrics.bytesRecv += recvSize;
                        ++unreliableChannelMetrics.numPacketsRecv;
                    }
                    if (error == (byte)NetworkError.MessageToLong)
                    {
                        callbacks.OnInvalidMessageReceived(conn);
                    }
                    else
                    {
                        callbacks.OnMessageReceived(conn, recvBuffer, recvSize);
                    }
                }
            } break;

            default:
                return;
            }
        }
    }
    void Recv(SocketNetDriverConnection connection, INetDriverCallbacks callbacks, Socket socket, byte[] buffer, ref NetIOMetrics metrics, bool isDatagram)
    {
        Perf.Begin("SocketNetDriver.Recv");

        if (isDatagram)
        {
            while (connection.isValid && (socket.Available > 0))
            {
                int r;
                try {
                    r = socket.Receive(buffer, 0, World.MAX_UNRELIABLE_MESSAGE_SIZE, SocketFlags.None);
                    if (r <= 0)
                    {
                        throw new SocketException((int)SocketError.SocketError);
                    }
                    metrics.bytesRecv += r;
                    ++metrics.numPacketsRecv;
                } catch (Exception e) {
                    Debug.LogException(e);
                    callbacks.OnInvalidMessageReceived(connection);
                    continue;
                }

                if (!connection.didHandshake)
                {
                    // client may receive a UDP packet before receiving control ACK
                    // so discard the packet until we process the ACK.
                    continue;
                }

                callbacks.OnMessageReceived(connection, buffer, r);
            }
        }
        else
        {
            while (connection.isValid && (socket.Available > 0))
            {
                if (connection.pendingRecvSize <= 0)
                {
                    if (socket.Available < 2)
                    {
                        break;
                    }

                    // read from socket.
                    if (socket.Receive(connection.pendingBytes, 0, 2, SocketFlags.None) != 2)
                    {
                        throw new SocketException((int)SocketError.SocketError);
                    }

                    connection.pendingRecvSize      = ((int)connection.pendingBytes[0]) | (((int)connection.pendingBytes[1]) << 8);
                    connection.pendingBytesReceived = 0;

                    if (connection.pendingRecvSize > connection.pendingBytes.Length)
                    {
                        callbacks.OnInvalidMessageReceived(connection);
                        continue;
                    }
                }

                {
                    // read from socket.
                    var numBytesToRead = Mathf.Min(socket.Available, connection.pendingRecvSize - connection.pendingBytesReceived);
                    if (numBytesToRead > 0)
                    {
                        if (socket.Receive(connection.pendingBytes, connection.pendingBytesReceived, numBytesToRead, SocketFlags.None) != numBytesToRead)
                        {
                            throw new SocketException((int)SocketError.SocketError);
                        }
                        connection.pendingBytesReceived += numBytesToRead;
                    }
                }

                Assert.IsTrue(connection.pendingBytesReceived <= connection.pendingRecvSize);

                if (connection.pendingBytesReceived >= connection.pendingRecvSize)
                {
                    if (!connection.didHandshake)
                    {
                        if (callbacks == _clientCallbacks)
                        {
                            if (connection.channelID == -1)
                            {
                                var id = RecvControl(connection.pendingBytes, connection.pendingRecvSize);
                                if (id == -1)
                                {
                                    connection.Dispose();
                                    break;
                                }
                                connection.channelID   = id;
                                _sendUdpControlTimeout = UDP_CONTROL_RESEND_TIMEOUT;
                                SendUdpControl(connection);
                            }
                            else if (connection.pendingBytes[0] == (byte)EControlCode.AckChannelID)
                            {
                                connection.didHandshake = true;
                                callbacks.OnConnect(connection);
                            }
                            else
                            {
                                // invalid response
                                connection.Dispose();
                                break;
                            }
                        }
                        else
                        {
                            connection.Dispose();
                            break;
                        }

                        connection.pendingRecvSize      = 0;
                        connection.pendingBytesReceived = 0;
                        continue;
                    }

                    Array.Copy(connection.pendingBytes, buffer, connection.pendingRecvSize);

                    var r = connection.pendingRecvSize;

                    connection.pendingBytesReceived = 0;
                    connection.pendingRecvSize      = 0;

                    metrics.bytesRecv += r;
                    ++metrics.numPacketsRecv;

                    callbacks.OnMessageReceived(connection, buffer, r);
                    continue;
                }

                // not enough data ready
                break;
            }
        }

        Perf.End();
    }
    void RecvFrom(INetDriverCallbacks callbacks, Socket socket, byte[] buffer, ref NetIOMetrics metrics)
    {
        Perf.Begin("SocketNetDriver.RecvFrom");

        while (socket.Available > 0)
        {
            int r;

            try {
                r = socket.ReceiveFrom(buffer, 0, World.MAX_UNRELIABLE_MESSAGE_SIZE, SocketFlags.None, ref _recvEndPoint);
            } catch (Exception e) {
                Debug.LogException(e);

                SocketNetDriverConnection conn;
                if (_udpConnections.TryGetValue(_recvEndPoint, out conn))
                {
                    callbacks.OnInvalidMessageReceived(conn);
                }

                continue;
            }

            if (r <= 0)
            {
                throw new SocketException((int)SocketError.SocketError);
            }

            metrics.bytesRecv += r;
            ++metrics.numPacketsRecv;

            SocketNetDriverConnection connection;
            if (_udpConnections.TryGetValue(_recvEndPoint, out connection))
            {
                if (connection.isValid)
                {
                    if (r > 3)
                    {
                        // currently NetMsgs are always more than 3 bytes, and this guarantees that we don't
                        // try to process a duplicated control udp control message.

                        callbacks.OnMessageReceived(connection, buffer, r);
                    }
                }
            }
            else
            {
                // is this a control code?
                var id = RecvControl(buffer, r);
                if (id != -1)
                {
                    for (int i = 0; i < _tcpConnections.Values.Count; ++i)
                    {
                        var c = _tcpConnections.Values[i];
                        if (c.channelID == id)
                        {
                            if (_udpConnections.Values.Contains(c))
                            {
                                Debug.LogWarning("UDP control message received for registered channel.");
                            }
                            else
                            {
                                c.udpEndpoint = new IPEndPoint(((IPEndPoint)_recvEndPoint).Address, ((IPEndPoint)_recvEndPoint).Port);
                                _udpConnections.Add(c.udpEndpoint, c);
                                SendTcpControlAck(c);
                                c.didHandshake = true;
                                callbacks.OnConnect(c);
                                break;
                            }
                        }
                    }
                }
            }
        }

        Perf.End();
    }
Beispiel #16
0
 internal LocalGameNetDriverConnection(LocalGameNetDriver netDriver, INetDriverCallbacks callbacks)
 {
     this.netDriver = netDriver;
     this.callbacks = callbacks;
 }