public bool Listen(int port, int maxConnections, INetDriverCallbacks callbacks) { Assert.IsNull(clientSend); Assert.IsNull(serverSend); serverSend = new LocalGameNetDriverConnection(this, callbacks); return(true); }
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); }
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); }
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); }
public void Dispose() { if (callbacks != null) { callbacks.OnDisconnect(this); callbacks = null; netDriver.Disconnect(this); } }
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); }
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; }
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); }
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); }
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(); }
internal LocalGameNetDriverConnection(LocalGameNetDriver netDriver, INetDriverCallbacks callbacks) { this.netDriver = netDriver; this.callbacks = callbacks; }