I've been working the last weeks with a tcp protocol to send packet from arduino to unity using this code:
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
public class TCPConnection : MonoBehaviour
{
public string IP_Seat = "192.168.137.161";
public int port = 34197;
#region private members
private TcpClient socketConnection;
private Thread clientReceiveThread;
public float a, b, c, vel;
public float test = 0.0f;
#endregion
// Use this for initialization
void Awake()
{
ConnectToTcpServer();
}
/// <summary>
/// Setup socket connection.
/// </summary>
private void ConnectToTcpServer()
{
try
{
clientReceiveThread = new Thread(new ThreadStart(ListenForData));
clientReceiveThread.IsBackground = true;
clientReceiveThread.Start();
}
catch (Exception e)
{
Debug.Log("On client connect exception " + e);
}
}
/// <summary>
/// Runs in background clientReceiveThread; Listens for incomming data.
/// </summary>
private void ListenForData()
{
var aold = 0.0f;
var bold = 0.0f;
var cold = 0.0f;
var velold = 0.0f;
try
{
socketConnection = new TcpClient(IP_Seat, port);
//cketConnection.ConnectAsync(IP_Seat, port); // non si connette
//socketConnection.Client.Blocking = false;
//socketConnection.Client.ConnectAsync(IP_Seat,port);
Byte[] bytes = new Byte[16];
while (socketConnection.Connected)
{
// Get a stream object for reading
using (NetworkStream stream = socketConnection.GetStream())
{
int length;
// Read incomming stream into byte arrary.
while ((length = stream.Read(bytes, 0, bytes.Length)) != 0)
{
//Debug.Log("I'm receiving Data");
if (length == 16)
{
//Debug.Log("I'm receiving len 16 and I like it");
var incommingData = new byte[length];
var A = new Byte[4];
var B = new Byte[4];
var C = new Byte[4];
var VEL = new Byte[4];
Array.Copy(bytes, 0, incommingData, 0, length);
// Convert byte array to string message.
string serverMessage = Encoding.ASCII.GetString(incommingData);
Array.Copy(bytes, 0, A, 0, 4);
Array.Copy(bytes, 4, B, 0, 4);
Array.Copy(bytes, 8, C, 0, 4);
Array.Copy(bytes, 12, VEL, 0, 4);
a = BitConverter.ToSingle(A, 0) < 0 ? BitConverter.ToSingle(A, 0) : aold;
b = BitConverter.ToSingle(B, 0) < 0 ? BitConverter.ToSingle(B, 0) : bold;
c = BitConverter.ToSingle(C, 0) < 0 ? BitConverter.ToSingle(C, 0) : cold;
vel = BitConverter.ToSingle(VEL, 0); //< 0 ? BitConverter.ToSingle(C, 0) : 0;
//Debug.Log("server message received as: " + serverMessage +a +" "+b + " " + c + " " + vel);
aold = a;
bold = b;
cold = c;
velold = vel;
}
else {
//evitare che bilancia aspetti ack di tcp
}
}
}
}
}
catch (SocketException socketException)
{
Debug.Log("Socket exception: " + socketException);
}
}
}
and right now i'm having blocking issues: i'd like to use the async method for the TCP but the tcpClient.ConnectAsync
but it returns a SocketEXception and I can't figure out why.
The arduino sends 4 float in 16 bytes packet and 98-99% of them arrive correctly, but the missing 1-2% causes the system to block and an undesirable behaviour ( since i'm programming a device I need no delay waiting for an ack or a packet)
How can I make this sokcet async?
As @jdweng already said: TCP is just an undefined stream of data you need to implement an according protocol for knowing when a message ends (is fully received) and when a new one starts.
Now in your case you seem to already know that you have exactly 16
bytes.
Not the other parameter of NetworkStream.Read
which is
int offset -> The location in buffer to begin storing the data to.
what you want to do is wait until the buffer is actually full like
var receivedBytes = 0;
while (receivedBytes < bytes.Length)
{
receivedBytes += stream.Read(bytes, receivedBytes, bytes.Length - receivedBytes);
}
// Use bytes
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.