Hello guys,
I am working on a unity project where user can send data from client to server using TCP/IP. I am able to send the data. But my unity stalls or freeze until the data got read from the networkstream.
Server Code:Read Data.
void Start () {
StartServer ();
startServerButton.interactable = true;
closeServerButton.interactable = false;
}
public void StartServer (){
// Start TcpServer background thread
tcpListenerThread = new Thread (new ThreadStart(ListenForIncommingRequests));
tcpListenerThread.IsBackground = true;
tcpListenerThread.Start();
startServerButton.interactable = false;
path = UnityEditor.EditorUtility.SaveFolderPanel ("Any type of File.", "", ""); // Path.Combine(path,"D:\\Siva\\TCPDownloadfiles");
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.Space)) {
SendMessage();
}
if (myBackgroundWorker != null) myBackgroundWorker.Update();
}
/// <summary>
/// Runs in background TcpServerThread; Handles incomming TcpClient requests
/// </summary>
private void ListenForIncommingRequests () {
// Thread threadForDownloading = new Thread (new ThreadStart(DownloadingStreamData));
// threadForDownloading.IsBackground = true;
// threadForDownloading.Start();
DownloadingStreamData ();
}
private void DownloadingStreamData()
{
try {
Debug.Log("Befor Background work ........."+Thread.CurrentThread.Name);
if (myBackgroundWorker != null) myBackgroundWorker.CancelAsync();
myBackgroundWorker = new BackgroundThreading();
fileCount++;
int fileNameLen;
byte[] incommingData = new byte[1024];
string ext = "";
// Create listener on localhost port 8052.
tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 8052);
tcpListener.Start();
Debug.Log("Server is listening");
bytes = new Byte[Int32.MaxValue]; // 2221024
while (true) {
connectedTcpClient = tcpListener.AcceptTcpClient();
stream = connectedTcpClient.GetStream();
myBackgroundWorker.BackgroundWorkStart += (obj, attr) =>
{
if (attr.IsCanceled) return;
Debug.Log("Background work In Progress...");
do{
// IAsyncResult result = stream.BeginRead(bytes, 0, bytes.Length, MessageReceived, stream);
// result.AsyncWaitHandle.WaitOne();
Debug.Log("Befor Stream Read.........."+Thread.CurrentThread.Name+" a.result : "+attr.Result+" attr.argument : "+attr.Argument+";");
length = stream.Read(bytes, 0, bytes.Length);
Debug.Log("After Stream Read.........."+length);
incommingData = new byte[length];
Array.Copy(bytes, 0, incommingData, 0, length - 4);
// Convert byte array to string message.
fileNameLen = BitConverter.ToInt32(incommingData, 0);
string clientMessage = Encoding.ASCII.GetString(incommingData,4, fileNameLen);
ext = Path.GetExtension(clientMessage);
//Debug.Log("client message received as: " + clientMessage);
//File.WriteAllBytes(path + "\ emp"+fileCount.ToString()+ext, incommingData);
// Read incomming stream into byte arrary.
}while(stream.DataAvailable);
BinaryWriter bWrite = new BinaryWriter(File.Open(path + "\ emp"+fileCount.ToString()+ext, FileMode.Create)); ;
bWrite.Write(incommingData, 4 + fileNameLen, length - 4 - fileNameLen);
bWrite.Flush();
bWrite.Close();
//Debug.Log("Bytes length2 :>>>"+" "+fileNameLen +" Incoming data length" +incommingData.Length);
//connectedTcpClient.Close();
//stream.Flush();
//stream.Close();
};
myBackgroundWorker.BackgroundWorkCompleted += (obj, attr) =>
{
Debug.Log("Background work was completed..."+Thread.CurrentThread.Name+" attr.result : "+attr.Result+" Error :"+attr.Error);
};
myBackgroundWorker.RunWorkerAsync("Test");
}
}
catch (SocketException socketException) {
Debug.Log("SocketException " + socketException.ToString());
}
}
/// <summary>
/// Send message to client using socket connection.
/// </summary>
public void SendMessage() {
if (connectedTcpClient == null) {
return;
}
try {
// Get a stream object for writing.
NetworkStream stream = connectedTcpClient.GetStream();
if (stream.CanWrite) {
string serverMessage = "This is a message from your server.";
// Convert string message to byte array.
byte[] serverMessageAsByteArray = Encoding.ASCII.GetBytes(serverMessage);
// Write byte array to socketConnection stream.
stream.Write(serverMessageAsByteArray, 0, serverMessageAsByteArray.Length);
Debug.Log("Server sent his message - should be received by client");
}
}
catch (SocketException socketException) {
Debug.Log("Socket exception: " + socketException);
}
}
//Callback called when "BeginRead" is ended
private void MessageReceived(IAsyncResult result)
{
Debug.Log("On MessageReceived::::::::::::::::::::::::::");
//length = stream.Read(bytes, 0, bytes.Length);
if (result.IsCompleted && connectedTcpClient.Connected)
{
//build message received from client
s_bytesReceived = stream.EndRead(result); //End async reading
//s_receivedMessage = Encoding.ASCII.GetString(bytes, 0, s_bytesReceived); //De-encode message as string
Debug.Log("result.IsCompleted on MessageReceived::::::::::::::::::::::::::"+s_bytesReceived);
}
}
public void CloseServer()
{
Debug.Log("Server Closed");
//Close client connection
if (connectedTcpClient != null)
{
stream.Close ();
stream = null;
connectedTcpClient.Close();
connectedTcpClient = null;
}
//Close server connection
if(tcpListener != null)
{
tcpListener.Stop();
tcpListener = null;
startServerButton.interactable = true;
closeServerButton.interactable = false;
}
}
}
I tried using stream.BeginRead method but that is throwing exception like Stream/socket was disposed already and trying to access it on client code.
But stream.Read method works as like i expect but it stalls/freeze the unity until it get the data.Please give me some better solution for this issue. Thanks in advance.
Client Code: Sends Data
if (stream.CanWrite) {
string path = UnityEditor.EditorUtility.OpenFilePanel (“Any type of File.”, “”, “”);
WWW www = new WWW (“file:///” + path);
byte[] fileNameBytes = Encoding.ASCII.GetBytes(path);
byte[] fileDataBytes = www.bytes;
byte[] fileNameLength = BitConverter.GetBytes(fileNameBytes.Length);
clientData = new byte[4 + fileNameBytes.Length + fileDataBytes.Length];
fileNameLength.CopyTo(clientData, 0);
fileNameBytes.CopyTo(clientData, 4);
fileDataBytes.CopyTo(clientData, 4 + fileNameBytes.Length);
Debug.Log ("FIle sends to server path : "+path);
//stream.BeginRead(clientData, 0, clientData.Length, MessageReceived, stream);
try {
stream.Write(clientData, 0, clientData.Length);
//stream.BeginWrite(clientData, 0, clientData.Length, MessageReceived, stream);
}catch (Exception e) {
Debug.Log("SocketException " + e.ToString());
}