TCP 客户端有时会合并数据包
TCP Client sometimes merges data-packets
在 Unity 应用程序中,我每秒通过 TCP 接收大约 160 个 JSON 对象。我下面的阅读代码似乎以这样的速度挣扎,并且有几次没有 processData
它们作为单个消息。当尝试创建一个 JSONObject` 而不是我得到这样的东西时
improper JSON
formatting:right","data":{"type":"flex","gesture":"open","data":[0.11425240454677936,0.11582253631723596,0.0947054436987323,0]}}{"type":"right","data":{"type":"sensor","data":[0.98638916015625,-0.0802001953125,0.08880615234375,-0.11248779296875,null]}}{"type":"right","data":{"type":"flex","gesture":"open","data":[0.11192072282133489,0.11739301138594425,0.09271687795177729,0]}}{"type":"right","data":{"type":"sensor","data":[0.98638916015625,-0.0802001953125,0.08880615234375,-0.11248779296875,null]}}{"type":"right",
这是我的数据处理函数:
bool ProcessData()
{
string temp = System.Text.Encoding.Default.GetString(readBuffer);
//Debug.Log(string.Format("Client recv: '{0}'", temp));
JSONObject obj = new JSONObject(temp);
}
这是我的 TCP 代码:
void connectToHub () {
readBuffer = new byte[512];
EndPoint endpoint;
if (this.useUnixSocket == true) {
endpoint = new UnixEndPoint(SOCKET_LOCATION);
} else {
endpoint = new IPEndPoint(this.ipAdress, this.port);
}
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try {
IAsyncResult result = client.BeginConnect(endpoint,
new AsyncCallback(this.EndConnect),
null);
bool connectSuccess = result.AsyncWaitHandle.WaitOne(System.TimeSpan.FromSeconds(10));
if (!connectSuccess){
client.Close();
Debug.LogError(string.Format("Client unable to connect. Failed"));
}
}
catch(SystemException e) {
Debug.LogError(string.Format("Client exception on beginconnect: {0}", e.Message));
}
}
void EndConnect(IAsyncResult iar)
{
client.EndConnect(iar);
client.NoDelay = true;
ReceiveData();
}
void ReceiveData()
{
client.BeginReceive(readBuffer, 0, readBuffer.Length, SocketFlags.None, EndReceiveData, client);
}
void EndReceiveData(System.IAsyncResult iar)
{
int numBytesReceived = client.EndReceive(iar);
if (numBytesReceived > 0){
this.ProcessData();
}
// Continue receiving data
ReceiveData();
}
在我看来,有时您在数据全部到达之前就开始处理数据。当您通过 TCP 接收到一些数据时,您正在调用 EndReceiveData
。如果所有的数据都装进刚刚到达的数据包,你就没有问题。但是,如果数据大于数据包,那么在开始解析之前,您确实应该读取该 json 对象的所有数据包。
在 Unity 应用程序中,我每秒通过 TCP 接收大约 160 个 JSON 对象。我下面的阅读代码似乎以这样的速度挣扎,并且有几次没有 processData
它们作为单个消息。当尝试创建一个 JSONObject` 而不是我得到这样的东西时
improper JSON formatting:right","data":{"type":"flex","gesture":"open","data":[0.11425240454677936,0.11582253631723596,0.0947054436987323,0]}}{"type":"right","data":{"type":"sensor","data":[0.98638916015625,-0.0802001953125,0.08880615234375,-0.11248779296875,null]}}{"type":"right","data":{"type":"flex","gesture":"open","data":[0.11192072282133489,0.11739301138594425,0.09271687795177729,0]}}{"type":"right","data":{"type":"sensor","data":[0.98638916015625,-0.0802001953125,0.08880615234375,-0.11248779296875,null]}}{"type":"right",
这是我的数据处理函数:
bool ProcessData()
{
string temp = System.Text.Encoding.Default.GetString(readBuffer);
//Debug.Log(string.Format("Client recv: '{0}'", temp));
JSONObject obj = new JSONObject(temp);
}
这是我的 TCP 代码:
void connectToHub () {
readBuffer = new byte[512];
EndPoint endpoint;
if (this.useUnixSocket == true) {
endpoint = new UnixEndPoint(SOCKET_LOCATION);
} else {
endpoint = new IPEndPoint(this.ipAdress, this.port);
}
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try {
IAsyncResult result = client.BeginConnect(endpoint,
new AsyncCallback(this.EndConnect),
null);
bool connectSuccess = result.AsyncWaitHandle.WaitOne(System.TimeSpan.FromSeconds(10));
if (!connectSuccess){
client.Close();
Debug.LogError(string.Format("Client unable to connect. Failed"));
}
}
catch(SystemException e) {
Debug.LogError(string.Format("Client exception on beginconnect: {0}", e.Message));
}
}
void EndConnect(IAsyncResult iar)
{
client.EndConnect(iar);
client.NoDelay = true;
ReceiveData();
}
void ReceiveData()
{
client.BeginReceive(readBuffer, 0, readBuffer.Length, SocketFlags.None, EndReceiveData, client);
}
void EndReceiveData(System.IAsyncResult iar)
{
int numBytesReceived = client.EndReceive(iar);
if (numBytesReceived > 0){
this.ProcessData();
}
// Continue receiving data
ReceiveData();
}
在我看来,有时您在数据全部到达之前就开始处理数据。当您通过 TCP 接收到一些数据时,您正在调用 EndReceiveData
。如果所有的数据都装进刚刚到达的数据包,你就没有问题。但是,如果数据大于数据包,那么在开始解析之前,您确实应该读取该 json 对象的所有数据包。