private static void EndReliableSend(IAsyncResult asyncResult) { //Extract ReliableTransmissionState from Async State TcpTransmissionState transmissionState = (TcpTransmissionState)asyncResult.AsyncState; TcpClient tcpClient = transmissionState.tcpClient; try { NetworkStream stream = tcpClient.GetStream(); stream.EndWrite(asyncResult); //Callback of transmission state if (transmissionState.callback != null) { transmissionState.callback(); } } catch (Exception ex) { if (!client.connected || !client.tcpClient.Connected) { return; } Debug.LogError("Error sending reliable packet to server: " + ex); } }
public static void SendReliable(Packet packet, Action callback = null) { if (!connected || !client.tcpClient.Connected) { Debug.LogError("Can't send Packet while not connected!"); return; } if (packet.data == null) { Debug.LogError("Data to be sent is null!"); return; } if (packet.data.Length == 0) { Debug.LogError("Data to be sent is empty!"); return; } //Must split packets if (packet.data.Length > NUUtilities.MTU) { Packet[] partPackets = NUUtilities.SplitPacket(packet); for (int i = 0; i < partPackets.Length - 1; i++) { SendReliable(partPackets[i]); } //Set callback on last packet send SendReliable(partPackets[partPackets.Length - 1], callback); return; } try { TcpTransmissionState transmissionState = new TcpTransmissionState(packet.data.Length, ref client.tcpClient, client, callback); client.tcpClient.GetStream().BeginWrite(packet.data, 0, packet.data.Length, new AsyncCallback(EndReliableSend), transmissionState); } catch (Exception ex) { if (!client.connected || !client.tcpClient.Connected) { return; } Debug.LogError("Error sending reliable Packet to Server: " + ex.ToString()); //Do proper disconnection handling hasDisconnected = true; } }
private static void EndReliableReceive(IAsyncResult asyncResult) { //Extract TransmissionState from Async State TcpTransmissionState transmissionState = (TcpTransmissionState)asyncResult.AsyncState; TcpClient tcpClient = transmissionState.tcpClient; try { //End receiving data NetworkStream stream = tcpClient.GetStream(); int receivedSize = stream.EndRead(asyncResult); int packetItt = 0; //Iterator for packets bytes //Create all packets within this buffer while (receivedSize > 0) { //Read packet size from the beginning of the packet buffer int packetSize; //Check if the end of the buffer match partial packet size data if (packetItt > transmissionState.data.Length - 4) { packetSize = -1; } else { packetSize = BitConverter.ToInt32(transmissionState.data, packetItt); if (packetSize < 0) { Debug.LogError("Error while receiving reliable packet! Size is negative: " + packetSize); return; } } //Check if there is missing packet data if (receivedSize + transmissionState.offset < packetSize || packetSize == -1) { //Append received data to buffer (next EndRead will append remaining data on it) Array.Copy(transmissionState.data, packetItt + transmissionState.offset, transmissionState.data, transmissionState.offset, receivedSize); //Hold received size so far to check for packet completition later transmissionState.offset += receivedSize; //Keep receiving this packet with offset stream.BeginRead(transmissionState.data, transmissionState.offset, NUUtilities.MTU - transmissionState.offset, new AsyncCallback(EndReliableReceive), transmissionState); //This receive operation stops here return; } //Update current size (is the same as the data ID for this packet!) receivedSize -= packetSize - transmissionState.offset; //Create packet from raw data Packet packet = new Packet(transmissionState.data, packetItt, packetSize); //Treat packet accordingly TreatPacket(ref packet); //Reset transmissionState offset transmissionState.offset = 0; //Increment packet iterator packetItt += packetSize; } //Keep receiving data if (tcpClient.Connected) { stream.BeginRead(transmissionState.data, 0, NUUtilities.MTU, new AsyncCallback(EndReliableReceive), transmissionState); } else { hasDisconnected = true; } } catch (Exception ex) { if (!client.connected || !tcpClient.Connected) { return; } Debug.LogError("Error occurred receiving reliable packet from server: " + ex.ToString()); //Do proper disconnection handling hasDisconnected = true; } }
private static void EndConnect(IAsyncResult asyncResult) { //Extract TcpClient from AsyncState TcpClient tcpClient = (TcpClient)asyncResult.AsyncState; //Try to connect to the given EndPoint try { //Finish connecting tcpClient.EndConnect(asyncResult); //Get Client EndPoint IPEndPoint localEndPoint = (IPEndPoint)tcpClient.Client.LocalEndPoint; IPEndPoint remoteEndPoint = (IPEndPoint)tcpClient.Client.RemoteEndPoint; //Create UdpClient Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp) { ExclusiveAddressUse = true }; udpClient.Bind(localEndPoint); //Bind it locally to the TCP Address //Create NUClientInfo if it doesn't exists already if (client == null) { client = new NUClientInfo(Guid.Empty, localEndPoint.Address, ref tcpClient, ref udpClient); } else { //Override information with last client id but current addresses and sockets client = new NUClientInfo(client.guid, localEndPoint.Address, ref tcpClient, ref udpClient); } //Debug.Log("Connected to server (" + remoteEndPoint.Address + ":" + remoteEndPoint.Port + ")!" + // "\nSending GUID " + client.id + " and Waiting for response..."); //Send Current GUID - Null if this is not a reconnect Packet guidPacket = new Packet(client.guid.ToByteArray(), null, Packet.TypeFlag.GUID, NUUtilities.GeneratePacketId()); TcpTransmissionState transmissionState = new TcpTransmissionState(guidPacket.data.Length, ref tcpClient, client, null); tcpClient.GetStream().BeginWrite(guidPacket.data, 0, guidPacket.data.Length, new AsyncCallback(EndReliableSend), transmissionState); //Start receiving messages from server TcpTransmissionState tcpTransmissionState = new TcpTransmissionState( NUUtilities.MTU, ref tcpClient, client, null); tcpClient.GetStream().BeginRead(tcpTransmissionState.data, 0, NUUtilities.MTU, new AsyncCallback(EndReliableReceive), tcpTransmissionState); UdpTransmissionState udpTransmissionState = new UdpTransmissionState( NUUtilities.MTU, ref udpClient, client, null); udpClient.BeginReceive(udpTransmissionState.data, 0, NUUtilities.MTU, SocketFlags.None, new AsyncCallback(EndUnreliableReceive), udpTransmissionState); Debug.Log("Connected to Server!"); } catch (Exception ex) { //Setup disconnection flag hasDisconnected = true; Debug.LogError("Could not connect to Server! " + ex.ToString()); return; } }