I'm trying to create a TCP Client-Server connection, the client can connect to the server successfully, but I can't receive the data I'm sending from the server and I get this Error:
NullReferenceException: Object reference not set to an instance of an object ClientHandlePackets.HandleDataPackets (System.Byte[] data) (at Assets/Client/Scripts/ClientHanlePackets.cs:89) ClientHandlePackets.HandleData (System.Byte[] data) (at Assets/Client/Scripts/ClientHanlePackets.cs:61) ClientTCP.Update () (at Assets/Client/Scripts/ClientTCP.cs:31)
How can I Solve this?
c#
using System.Collections.Generic;
using UnityEngine;
public enum ServerPackets
{
S_INFORMATION = 1,
S_EXECUTEMETHODONCLIENT,
}
public class ClientHandlePackets : MonoBehaviour
{
public static Bytebuffer playerbuffer;
public delegate void Packet_(byte[] data);
private static Dictionary<long, Packet_> packets;
private static long pLength;
private void Awake()
{
initalizePackets();
}
private static void initalizePackets()
{
packets = new Dictionary<long, Packet_>();
packets.Add((long)ServerPackets.S_INFORMATION, PacketInformation);
}
public static void HandleData(byte[] data)
{
byte[] Buffer;
Buffer = (byte[])data.Clone();
if (playerbuffer == null) { playerbuffer = new Bytebuffer(); };
playerbuffer.WriteBytes(Buffer);
if (playerbuffer.Count() == 0)
{
playerbuffer.Clear();
return;
}
if (playerbuffer.Length() >= 8)
{
pLength = playerbuffer.ReadLong(false);
if (pLength <= 0)
{
playerbuffer.Clear();
return;
}
}
while (pLength > 0 & pLength <= playerbuffer.Length() - 8)
{
if (pLength <= playerbuffer.Length() - 8)
{
playerbuffer.ReadLong(); //REads out the packet identifier
data = playerbuffer.Readbytes((int)pLength); // Gets the full package length
HandleDataPackets(data);
}
pLength = 0;
if (playerbuffer.Length() >= 8)
{
pLength = playerbuffer.ReadLong(false);
if (pLength < 0)
{
playerbuffer.Clear();
return;
}
}
}
}
private static void HandleDataPackets(byte[] data)
{
long packetIdentifier;
Bytebuffer Buffer;
Packet_ packet;
Buffer = new Bytebuffer();
Buffer.WriteBytes(data);
packetIdentifier = Buffer.ReadLong();
Buffer.Dispose();
if (packets.TryGetValue(packetIdentifier, out packet))
{
packet.Invoke(data);
}
}
private static void PacketInformation(byte[] data)
{
Bytebuffer buffer = new Bytebuffer();
buffer.WriteBytes(data);
long packetIdentifier = buffer.ReadLong();
string msg1 = buffer.Readstring();
string msg2 = buffer.Readstring();
int Level = buffer.ReadInteger();
Debug.Log(msg1);
Debug.Log(msg2);
Debug.Log(Level);
}
}
using System;
using System.Net.Sockets;
using UnityEngine;
using UnityEngine.UI;
public class ClientTCP: MonoBehaviour
{
public Text info;
public static ClientTCP instance;
public TcpClient client;
public NetworkStream mystream;
private byte[] AsynchBuffer;
public bool IsConnected;
public byte[] Receivebyte;
public bool handleData = false;
private string IP_Adress= "127.0.0.1";
private int port=5555;
private void Awake()
{
instance = this;
}
private void Update()
{
if (handleData == true)
{
ClientHandlePackets.HandleData(Receivebyte);
handleData = false;
}
}
public void Connect()
{
Debug.Log("Trying to connect to the sever...");
client = new TcpClient();
client.ReceiveBufferSize = 4096;
client.SendBufferSize = 4096;
AsynchBuffer = new byte[8192];
try
{
client.BeginConnect(IP_Adress, port, new AsyncCallback(ConnectCallback), client);
}
catch
{
Debug.Log("unable to connect to the server");
}
}
private void ConnectCallback(IAsyncResult result)
{
try
{
client.EndConnect(result);
if (client.Connected == false)
{
return;
}
else
{
mystream = client.GetStream();
mystream.BeginRead(AsynchBuffer,0,8192,OnRecieveData,null);
IsConnected = true;
Debug.Log("You are connected to the server successfully!");
}
}
catch (Exception)
{
IsConnected = false;
return;
}
}
private void OnRecieveData(IAsyncResult result)
{
try
{
int packetlength = mystream.EndRead(result);
Receivebyte = new byte[packetlength];
Buffer.BlockCopy(AsynchBuffer, 0, Receivebyte, 0, packetlength);
if (packetlength == 0)
{
Debug.Log("disconnected");
Application.Quit();
return;
}
handleData = true;
mystream.BeginRead(AsynchBuffer, 0, 8192, OnRecieveData, null);
}
catch (Exception)
{
Debug.Log("disconnected");
Application.Quit();
return;
}
}
}
the problem is here:
if (packets.TryGetValue(packetIdentifier, out packet))
{
packet.Invoke(data);
}
to avoid this error you can use
if (packets.TryGetValue(packetIdentifier, out packet))
{
packet?.Invoke(data);
}
But the problem is that i don't see where you fill your packets' dictionary with data in your code.
Can you show your ByteBuffer class?
Related
Here is the error
NullReferenceException: Object reference not set to an instance of an object
Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckReadAndThrow (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) (at <13e6546058e340ada820e34dce3b245e>:0)
Unity.Collections.NativeList`1[T].get_Length () (at Library/PackageCache/com.unity.collections#1.2.4/Unity.Collections/NativeList.cs:227)
Unity.Networking.Transport.NetworkDriver+Concurrent.BeginSend (Unity.Networking.Transport.NetworkPipeline pipe, Unity.Networking.Transport.NetworkConnection id, Unity.Networking.Transport.DataStreamWriter& writer, System.Int32 requiredPayloadSize) (at Library/PackageCache/com.unity.transport#1.1.0/Runtime/NetworkDriver.cs:177)
Unity.Networking.Transport.NetworkDriver.BeginSend (Unity.Networking.Transport.NetworkConnection id, Unity.Networking.Transport.DataStreamWriter& writer, System.Int32 requiredPayloadSize) (at Library/PackageCache/com.unity.transport#1.1.0/Runtime/NetworkDriver.cs:1210)
Server.SendToClient (Unity.Networking.Transport.NetworkConnection connection, NetMessage msg) (at Assets/Scripts/Net/Server.cs:196)
Chessboard.OnWelcomeServer (NetMessage msg, Unity.Networking.Transport.NetworkConnection cnn) (at Assets/Scripts/Chessboard.cs:774)
NetWelcome.ReceivedOnServer (Unity.Networking.Transport.NetworkConnection cnn) (at Assets/Scripts/Net/NetMessage/NetWelcome.cs:32)
NetUtility.OnData (Unity.Networking.Transport.DataStreamReader stream, Unity.Networking.Transport.NetworkConnection cnn, Server server) (at Assets/Scripts/Net/NetUtility.cs:32)
Server.UpdateMessagePump () (at Assets/Scripts/Net/Server.cs:133)
Server.Update () (at Assets/Scripts/Net/Server.cs:121)
Code:
using Unity.Collections;
using System;
using Unity.Networking.Transport;
using UnityEngine;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Net;
public class Server : MonoBehaviour
{
public string GetLocalIpAddress()
{
UnicastIPAddressInformation mostSuitableIp = null;
var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (var network in networkInterfaces)
{
if (network.OperationalStatus != OperationalStatus.Up)
continue;
var properties = network.GetIPProperties();
if (properties.GatewayAddresses.Count == 0)
continue;
foreach (var address in properties.UnicastAddresses)
{
if (address.Address.AddressFamily != AddressFamily.InterNetwork)
continue;
if (IPAddress.IsLoopback(address.Address))
continue;
if (!address.IsDnsEligible)
{
if (mostSuitableIp == null)
mostSuitableIp = address;
continue;
}
// The best IP is the IP got from DHCP server
if (address.PrefixOrigin != PrefixOrigin.Dhcp)
{
if (mostSuitableIp == null || !mostSuitableIp.IsDnsEligible)
mostSuitableIp = address;
continue;
}
return address.Address.ToString();
}
}
return mostSuitableIp != null
? mostSuitableIp.Address.ToString()
: "";
}
#region Singeton implementation
public static Server Instance { set; get; }
private void Awake()
{
Instance = this;
}
#endregion
public NetworkDriver driver;
private NativeList<NetworkConnection> connections;
private bool isLocal = false;
private bool isActive = false;
private const float keepAliveTickRate = 20.0f;
private float lastKeepAlive;
public Action connectionDropped;
// Methods
public void Init(ushort port, bool localGame)
{
isLocal = localGame;
driver = NetworkDriver.Create();
NetworkEndPoint endPoint = NetworkEndPoint.Parse(GetLocalIpAddress(), port);
Debug.Log("TEST Local: " + endPoint.Address);
// endPoint.Port = port;
if (driver.Bind(endPoint) != 0)
{
Debug.Log("Unable to bind op port" + endPoint.Port);
}
else
{
driver.Listen();
Debug.Log("Currently listening on port" + endPoint.Port);
}
connections = new NativeList<NetworkConnection>(2, Allocator.Persistent);
isActive = true;
}
public void Shutdown()
{
if (isActive)
{
driver.Dispose();
connections.Dispose();
isActive = false;
}
}
public void OnDestroy()
{
Shutdown();
}
public void Update()
{
if (!isActive)
return;
KeepAlive();
driver.ScheduleUpdate().Complete();
CleanupConnections();
AcceptNewConnection();
UpdateMessagePump();
}
private void UpdateMessagePump()
{
DataStreamReader stream;
for (int i = 0; i < connections.Length; i++)
{
NetworkEvent.Type cmd;
while ((cmd = driver.PopEventForConnection(connections[i], out stream)) != NetworkEvent.Type.Empty)
{
if (cmd == NetworkEvent.Type.Data)
{
NetUtility.OnData(stream, connections[i], this);
}
else if (cmd == NetworkEvent.Type.Disconnect)
{
Debug.Log("Client disconnected from server");
connections[i] = default(NetworkConnection);
connectionDropped?.Invoke();
Shutdown(); // This is only if it is locah Host
}
}
}
}
// Server specific
private void KeepAlive()
{
if((Time.time - lastKeepAlive) > keepAliveTickRate)
{
lastKeepAlive = Time.time;
Broadcast(new NetKeepAlive());
}
}
private void CleanupConnections()
{
for (int i = 0; i < connections.Length; i++)
{
if (!connections[i].IsCreated)
{
connections.RemoveAtSwapBack(i);
--i;
}
}
}
private void AcceptNewConnection()
{
NetworkConnection c;
// Accept new connections
if (isLocal == true)
{
if (connections.Length == 0)
{
while ((c = driver.Accept()) != default(NetworkConnection))
{
connections.Add(c);
Debug.Log("New connection Added");
}
}
}
else if(isLocal == false)
{
if(connections.Length <= 1)
{
while ((c = driver.Accept()) != default(NetworkConnection))
{
connections.Add(c);
Debug.Log("New connection Added");
}
}
}
}
public void SendToClient(NetworkConnection connection, NetMessage msg)
{
DataStreamWriter writer;
driver.BeginSend(connection, out writer);
msg.Serialize(ref writer);
driver.EndSend(writer);
}
public void Broadcast(NetMessage msg)
{
for (int i = 0; i < connections.Length; i++)
if (connections[i].IsCreated)
{
// Debug.Log($"Sending {msg.Code} to : {connections[1].InternalId}");
SendToClient(connections[i], msg);
}
}
}
How do i fix it?
I build a middle ware server.
I have 5(or 6) clients(different computer/IP address), and every client can have up to 6 connection -> max 36 connection to the server.
It is better to use only 1 port for all (e.g. 9000) or one different port for every client(e.g. 9000-9005) ?
I write me a simple test server(see code).
It worked like expected but maybe there is some room for optimization.
Thanks
My TCP server
public class TCPServerMulti : IDisposable
{
private static TcpListener _tcpListener;
private string _ipAdress = "";
private int _port = 9050;
private readonly Thread _listener;
private readonly bool _running;
private int cc = 0; //Test Counter
public string IPAdress
{
get { return _ipAdress; }
set { _ipAdress = value; }
}
public TCPServerMulti(int port)
{
if(port>0)
_port = port;
_running = true;
string sHostName = Dns.GetHostName();
IPAdress = "";
//Only use the first address -> need to change
IPAddress[] localAddress = Dns.GetHostAddresses(sHostName);
foreach (IPAddress ipAddress in localAddress)
{
if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
{
_tcpListener = new TcpListener(ipAddress, _port);
IPAdress = ipAddress.ToString();
break;
}
}
if (IPAdress == "")
{
Console.Writeline("TCP Error");
return;
}
_tcpListener.Start();
_listener = new Thread(Listen) { IsBackground = true };
_listener.Start();
}
public TCPServerMulti():this(-1)
{}
//listening for clients
public void Listen()
{
try
{
while(_running)
{
cc++;
//create a own client object for every connection
TCPClientData cd = new TCPClientData(this, ""+cc, _tcpListener.AcceptTcpClient());
cd.StartClient();
if (ClientConnected != null) ClientConnected("Connected: " + cc);
}
_tcpListener.Stop();
}
catch (Exception)
{
}
}
public void Dispose()
{
_listener.Abort();
_tcpListener.Stop();
}
//Handle for Mainthread
internal void ReceiveClient(TCPClientData sender, string msg)
{
if (ReceiveMsg != null)
ReceiveMsg(sender, msg);
}
public delegate void ReceiveEventHandler(TCPClientData sender, string msg);
public event ReceiveEventHandler ReceiveMsg;
public delegate void ConnectedEventHandler(string msg);
public event ConnectedEventHandler ClientConnected;
}
Clientdata object
public class TCPClientData : IDisposable
{
private TCPServerMulti _master;
private byte[] _data;
private NetworkStream _networkStream;
private int _received;
private TcpClient _tcpClient;
private Thread _worker;
private bool _wrunning;
private string _id;
public TCPClientData(TCPServerMulti master,string id,TcpClient client)
{
_data = new byte[1024];
_master = master;
_id = id;
_tcpClient = client;
}
public string ID
{
get { return _id; }
}
private string ByteArrayToString(byte[] arr)
{
UTF8Encoding enc = new UTF8Encoding();
return enc.GetString(arr);
}
private byte[] StringToByteArray(string data)
{
UTF8Encoding enc = new UTF8Encoding();
return enc.GetBytes(data);
}
// Reading Data
private void Worker()
{
try
{
while (_wrunning)
{
if (_networkStream.DataAvailable)
{
_received = _networkStream.Read(_data, 0, _data.Length);
string s = ByteArrayToString(_data);
_master.ReceiveClient(this, s.Substring(0, _received));
}
else
{
Thread.Sleep(20);
}
}
_networkStream.Close();
_tcpClient.Close();
}
catch (Exception)
{ }
}
public void Dispose()
{
_worker.Abort();
_networkStream.Close();
_tcpClient.Close();
}
public void StartClient()
{
_networkStream = _tcpClient.GetStream();
_networkStream.ReadTimeout = 200;
_wrunning = true;
_worker = new Thread(Worker) { IsBackground = true };
_worker.Start();
}
public void StopClient()
{
_wrunning = false;
Thread.Sleep(700);
}
//Sending Data
public void WriteData(string msg)
{
byte[] b = StringToByteArray(msg);
_networkStream.Write(b,0,b.Length);
_networkStream.Flush();
}
}
Main Thread
static void Main(string[] args)
{
//Create Server
TCPServerPlugin.TCPServerMulti server=new TCPServerMulti(12345);
server.ClientConnected += Server_ClientConnected;
server.ReceiveMsg += Server_ReceiveMsg;
while (true)
{
}
}
//Callbacks
private static void Server_ClientConnected(string msg)
{
Console.WriteLine(msg);
}
private static void Server_ReceiveMsg(TCPClientData sender, string msg)
{
Console.WriteLine(string.Format("Sender: {0} -> MSG:{1}",sender.ID,msg));
if (msg == "!!X")
{
sender.Dispose();
sender = null;
}
else if(msg=="DATE")
sender.WriteData(DateTime.Now.ToLongDateString());
else if(msg=="TIME")
sender.WriteData(DateTime.Now.ToShortTimeString());
}
I create client application for read message from server. The client application has class SocketClient which has function ReadDataAsync() for read message from server like this.
namespace SocketAsync
{
public class SocketClient
{
IPAddress mServerIPAddress;
int mServerPort;
TcpClient mClient;
public SocketClient()
{
mClient = null;
mServerPort = -1;
mServerIPAddress = null;
}
public IPAddress ServerIPAddress
{
get
{
return mServerIPAddress;
}
}
public int ServerPort
{
get
{
return mServerPort;
}
}
public bool SetServerIPAddress(string _IPAddressServer)
{
IPAddress ipaddr = null;
if (!IPAddress.TryParse(_IPAddressServer, out ipaddr))
{
Debug.WriteLine("Invalid server IP supplied.");
return false;
}
mServerIPAddress = ipaddr;
return true;
}
public bool SetPortNumber(string _ServerPort)
{
int portNumber = 0;
if (!int.TryParse(_ServerPort.Trim(), out portNumber))
{
Debug.WriteLine("Invalid port number supplied, return.");
return false;
}
if (portNumber <= 0 || portNumber > 65535)
{
Debug.WriteLine("Port number must be between 0 and 65535.");
return false;
}
mServerPort = portNumber;
return true;
}
public async Task ConnectToServer()
{
if (mClient == null)
{
mClient = new TcpClient();
}
try
{
await mClient.ConnectAsync(mServerIPAddress, mServerPort);
Debug.WriteLine(
string.Format("Connected to server IP/Port: {0} / {1}",
mServerIPAddress, mServerPort));
ReadDataAsync(mClient);
}
catch (Exception excp)
{
Console.WriteLine(excp.ToString());
throw;
}
}
private async Task ReadDataAsync(TcpClient mClient)
{
try
{
StreamReader clientStreamReader = new StreamReader(mClient.GetStream());
char[] buff = new char[64];
int readByteCount = 0;
while (true)
{
readByteCount = await clientStreamReader.ReadAsync(buff, 0, buff.Length);
if (readByteCount <= 0)
{
Debug.WriteLine("Disconnected from server.");
mClient.Close();
break;
}
Debug.WriteLine(
string.Format("Received bytes: {0} - Message: {1}",
readByteCount, new string(buff)));
Array.Clear(buff, 0, buff.Length);
}
}
catch (Exception excp)
{
Console.WriteLine(excp.ToString());
throw;
}
}
}
}
ReadDataAsync() can show message in output but I want to show message in Form1. So I put the label1 in Form. I connect to server when click button1 like this.
namespace TestClient
{
public partial class Form1 : Form
{
SocketClient client = new SocketClient();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if(!client.SetServerIPAddress("127.0.0.1")||
!client.SetPortNumber("23000"))
{
Debug.WriteLine("Wrong IP Address or port");
return;
}
client.ConnectToServer();
string strInputUser = null;
}
Can I show message in ReadDataAsync() to Form1. How to do that?
Use events.
Create your own EventArgs to transport the messages:
public class MessageEventArgs : EventArgs
{
public string Message { get; private set; }
public MessageEventArgs(string message)
{
this.Message = message;
}
}
In your SocketClient class declare the event:
namespace SocketAsync
{
public class SocketClient
{
IPAddress mServerIPAddress;
int mServerPort;
TcpClient mClient;
public event EventHandler<MessageEventArgs> Message;
// your other code
}
}
Also in your SocketClient class, use (raise) the event in ReadDataAsync():
private async Task ReadDataAsync(TcpClient mClient)
{
try
{
StreamReader clientStreamReader = new StreamReader(mClient.GetStream());
char[] buff = new char[64];
int readByteCount = 0;
while (true)
{
readByteCount = await clientStreamReader.ReadAsync(buff, 0, buff.Length);
if (readByteCount <= 0)
{
Message?.Invoke(this, new MessageEventArgs("Disconnected from server."));
Debug.WriteLine("Disconnected from server.");
mClient.Close();
break;
}
Message?.Invoke(this, new MessageEventArgs(string.Format("Received bytes: {0} - Message: {1}",
readByteCount, new string(buff))));
Debug.WriteLine(
string.Format("Received bytes: {0} - Message: {1}",
readByteCount, new string(buff)));
Array.Clear(buff, 0, buff.Length);
}
}
catch (Exception excp)
{
Console.WriteLine(excp.ToString());
throw;
}
}
Finally, in your form, consume the event:
namespace TestClient
{
public partial class Form1 : Form
{
SocketClient client = new SocketClient();
public Form1()
{
InitializeComponent();
client.Message += Client_Message;
}
private void Client_Message(object sender, MessageEventArgs e)
{
label1.Invoke(new Action() => label1.Text = e.Message);
}
// your other code
}
}
I've been trying for several days to make the client detect it when the server connection is closed and make a loop of connection attempts until it detects the available connection (open the server) and when I try closing the connection with Client.Close and shutdown (shutdown.both) stops the application
thank you if you could help me that I'm not correcting mistakes or solving the code
[DllImport("winmm.dll", EntryPoint = "mciSendStringA")]
public static extern void mciSendStringA(string comandonow, string retornonow, long longitudnow, long callbacknow);
public static TcpClient QKICDdjIKo = new TcpClient();
static IPEndPoint MjDHEHn = null;
static IPHostEntry hostEntry;
static List<TcpClient> countConnections = new List<TcpClient>();
static StreamReader reader;
private static byte[] _readBuffer;
private static byte[] _tempHeader;
public static bool Connected { get; private set; }
public static bool Exiting { get; private set; }
//
public static int BUFFER_SIZE { get { return 1024 * 16; } } // 16KB
public static int HEADER_SIZE { get { return 4; } } // 4B
private static bool IsConnectionSuccessful = false;
private static ManualResetEvent TimeoutObject = new ManualResetEvent(false);
private static Exception socketexception;
public static bool isconnected;
public static void Connection()
{
TimeoutObject.Reset();
socketexception = null;
try
{
if (!QKICDdjIKo.Connected)
{
_readBuffer = new byte[BUFFER_SIZE];
_tempHeader = new byte[HEADER_SIZE];
hostEntry = Dns.GetHostEntry("noip host");
var ip = hostEntry.AddressList[0];
MjDHEHn = new IPEndPoint(IPAddress.Parse(ip.ToString()), 4004);
QKICDdjIKo.Connect(MjDHEHn); // Option 1
// QKICDdjIKo.BeginConnect("127.0.0.1", 4004, new AsyncCallback(khmcbmPmGPCfIOcPKOBONAbnGnfFIJnpREd), QKICDdjIKo); //Option 2
OperatingSystem os_info = Environment.OSVersion;
ConnectedVerify(Environment.UserName.ToString());
QKICDdjIKo.GetStream().BeginRead(_readBuffer, 0, _readBuffer.Length, ReadMSG, 0);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private static void CallBackMethod(IAsyncResult asyncresult)
{
try
{
IsConnectionSuccessful = false;
TcpClient tcpclient = asyncresult.AsyncState as TcpClient;
if (tcpclient.Client != null)
{
tcpclient.EndConnect(asyncresult);
IsConnectionSuccessful = true;
}
}
catch (Exception ex)
{
IsConnectionSuccessful = false;
socketexception = ex;
}
finally
{
TimeoutObject.Set();
}
}
public Form1()
{
InitializeComponent();
Connect();
}
public static void Connect()
{
while (!Exiting) // Main Connect Loop
{
if (!Connected)
{
Thread.Sleep(100 + new Random().Next(0, 250));
Connection();
Thread.Sleep(200);
Application.DoEvents();
}
while (Connected) // hold client open
{
Application.DoEvents();
Thread.Sleep(2500);
}
if (Exiting)
{
//QKICDdjIKo.Close();
return;
}
Thread.Sleep(3000 + new Random().Next(250, 750));
}
}
public static void ReadMSG(IAsyncResult now)
{
try
{
while (true)
{
reader = new StreamReader(QKICDdjIKo.GetStream());
Rd(reader.ReadLine());
QKICDdjIKo.GetStream().BeginRead(_readBuffer, 0, _readBuffer.Length, ReadMSG, 0);
}
}
catch
{
}
}
public static void HjoLNkEHFaqQCp(string texto)
{
try
{
StreamWriter DpBoDcECG = new StreamWriter(QKICDdjIKo.GetStream());
DpBoDcECG.WriteLine(texto);
DpBoDcECG.Flush();
}
catch
{
//
}
}
public static void Rd(string msg)
{
}
static void Status(string msg)
{
try
{
StreamWriter writer = new StreamWriter(QKICDdjIKo.GetStream());
writer.WriteLine("STATUS|" + msg);
writer.Flush();
}
catch
{
}
}
static void ConnectedVerify(string msg)
{
StreamWriter writer = new StreamWriter(QKICDdjIKo.GetStream());
writer.WriteLine("CONNECTED|" + msg);
writer.Flush();
}
static void usr(string msg)
{
StreamWriter writer = new StreamWriter(QKICDdjIKo.GetStream());
writer.WriteLine("USER|" + msg);
writer.Flush();
}
In Unity3d Webgl I download and write big file (about 100 mb and more) to cache (indexeddb).
I downloaded file with UnityWebRequest and write file in downloadHandler.
Sometimes after call filestream.Write() or filestream.Flush() Chrome will crash.
Exception not available, only crash tab of chrome.
Crash happens abount in 50 percent of dowloads.
public class Downloader : MonoBehaviour
{
public IEnumerator DownloadFileCoroutine(string url, string filePath, string clientName, int fileId, Action<int> downloadedCallback)
{
var currentWebRequest = UnityWebRequest.Get(url);
currentWebRequest.downloadHandler = new ToFileDownloadHandler(new byte[64 * 1024], filePath);
var downloadHendler = (currentWebRequest.downloadHandler as ToFileDownloadHandler);
currentWebRequest.Send();
while (!currentWebRequest.isDone && !currentWebRequest.isNetworkError && !currentWebRequest.isHttpError)
{
if (currentWebRequest.isNetworkError)
{
yield break;
}
}
if (currentWebRequest.isNetworkError)
{
downloadHendler.Cancel();
}
else
{
/// suceess
}
}
public class ToFileDownloadHandler : DownloadHandlerScript
{
private int _expected = -1;
private long _received = 0;
private readonly string _filepath;
private readonly FileStream _fileStream = null;
private bool _canceled = false;
public ToFileDownloadHandler(byte[] buffer, string filepath) : base(buffer)
{
CreateDir();
_filepath = filepath;
_fileStream = new FileStream(filepath, FileMode.Create, FileAccess.Write);
}
protected override byte[] GetData() { return null; }
protected override bool ReceiveData(byte[] data, int dataLength)
{
if (data == null || data.Length < 1)
{
return false;
}
_received += dataLength;
if (!_canceled)
{
_fileStream.Write(data, 0, dataLength);
_fileStream.Flush();
}
return true;
}
protected override float GetProgress()
{
if (_expected < 0) return 0;
return (float)_received / _expected;
}
protected override void CompleteContent()
{
_fileStream.Close();
_isComplete = true;
}
protected override void ReceiveContentLength(int contentLength)
{
_expected = contentLength;
}
public void Cancel()
{
if (_canceled) return;
_canceled = true;
if (_fileStream != null)
{
_fileStream.Close();
}
File.Delete(_filepath);
}
private void CreateDir()
{
cachePath = Application.persistentDataPath;
if (!Directory.Exists(cachePath))
{
Directory.CreateDirectory(cachePath);
}
}
}
}