问题描述
所以我在这里有两件事.一个与在Linux服务器上运行的python脚本对话的iPad应用程序.python脚本正在发送大小为〜1K字节至最大〜10K字节的iPad应用程序数据文件.我遇到了一个非常奇怪的事件,它每隔一段时间就会发生一次(例如,每100或200次尝试一次).
我知道正在发送数据的服务器上的python脚本正在正确发送数据,因为如上所述,在我的测试中,我有5台iPad运行该应用程序,只有1台iPad会出现此问题(只会发生此问题一小部分的时间...)
我在后台线程中盯着异步客户端套接字,如下所示:
AsyncClient_Thread = new Thread(()=> AsyncClient.StartClient());AsyncClient_Thread.IsBackground = true;AsyncClient_Thread.Start();公共无效StartClient(){//连接到远程设备.尝试 {//为套接字建立远程端点.字符串ipAddress = appDel.wallInteractionScreen.Host_WallServer;IPEndPoint remoteEP =新的IPEndPoint(IPAddress.Parse(ipAddress),端口);//创建一个TCP/IP套接字.ClientSocket =新的Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);//连接到远程端点.ClientSocket.BeginConnect(remoteEP,新的AsyncCallback(ConnectCallback),ClientSocket);connectDone.WaitOne();接收(ClientSocket);receiveDone.WaitOne();}捕获(异常e){Console.WriteLine("AsyncClient StartClient中的错误:");Console.WriteLine(e.Message);Console.WriteLine(e.StackTrace);}//Console.WriteLine("Finished StartClient");}
这是我的ReceiveCallback函数
私有静态无效ReceiveCallback(IAsyncResult ar){AppDelegate appDel =(AppDelegate)UIApplication.SharedApplication.Delegate;//我添加了此InvokeOnMainThread来查看它是否可以解决数据乱序问题",但是并没有解决appDel.InvokeOnMainThread(委托{Console.WriteLine("ReceiveCallback IsMainThread =" + NSThread.IsMain);尝试 {//检索状态对象和客户端套接字//从异步状态对象开始.StateObject状态=(StateObject)ar.AsyncState;套接字客户端= state.workSocket;//从远程设备读取数据.int bytesRead = client.EndReceive(ar);如果(bytesRead> 0){//可能会有更多数据,因此请存储到目前为止接收到的数据.字符串stuffWeReceived = Encoding.ASCII.GetString(state.buffer,0,bytesRead);字符串debugString ="~~ ReceiveCallback ~~ len =" + stuffWeReceived.Length +"bytesRead =" + bytesRead +:" + stuffWeReceived;如果(appDel.diagnosticsScreen.DebugAsyncReceiveBuffer_Switch.On){appDel.diagnosticsScreen.AppendToDebugLog(debugString);}Console.WriteLine(debugString);//发送要接收的数据appDel.wallInteractionScreen.ChitterChatter.ReceiveSomeData(stuffWeReceived);//获取其余数据.client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,新的AsyncCallback(ReceiveCallback),状态);} 别的 {//表示已收到所有字节.receiveDone.Set();}}捕获(异常e){Console.WriteLine("AsyncClient ReceiveCallback中的错误:");Console.WriteLine(e.Message);Console.WriteLine(e.StackTrace);}});}
这最终是我在C#端代码中的线程/锁定问题.我从头开始重写了锁定机制,现在有100%的时间可以正常工作.感谢所有帮助我了解这一点的人!
So I have two things runner here. An iPad application talking to a python script running on a linux server. The python script is sending the iPad application data files of size ~1K bytes up to ~10K bytes. I'm having a very strange event that's occurring every once in a while (like maybe once every 100 or 200 tries).
I modeled my Asynchronous Client Socket from this example. In the ReceiveCallback function that I've posted below, I receive data into my buffer like this:
string stuffWeReceived = Encoding.ASCII.GetString(state.buffer,0,bytesRead);
But my problem is, sometimes I receive data out of order. And I stress the word sometimes. In my test, I had 5 iPads running my application side by side, and was sending all 5 ipads the same exact data. 99.9% of the time they receive the data correctly and in the right order, but 0.1% of the time ONE iPad will receive data out of order.
Here is a console output example of data that is in the correct order:
I know the python script on the server that is sending the data is sending data correctly because, as I mentioned above, in my test I have 5 iPads running the application and only 1 iPad will have this problem (this problem only happens a fraction of a percentage of the time...)
I am staring my Asynchronous Client Socket in a background thread as seen below:
AsyncClient_Thread = new Thread(() => AsyncClient.StartClient());
AsyncClient_Thread.IsBackground = true;
AsyncClient_Thread.Start();
public void StartClient()
{
// Connect to a remote device.
try {
// Establish the remote endpoint for the socket.
string ipAddress = appDel.wallInteractionScreen.Host_WallServer;
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ipAddress), port);
// Create a TCP/IP socket.
ClientSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
ClientSocket.BeginConnect( remoteEP,
new AsyncCallback(ConnectCallback), ClientSocket);
connectDone.WaitOne();
Receive(ClientSocket);
receiveDone.WaitOne();
}
catch (Exception e) {
Console.WriteLine("Error in AsyncClient StartClient: ");
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
// Console.WriteLine("Finished StartClient");
}
Here is my ReceiveCallback function
private static void ReceiveCallback( IAsyncResult ar )
{
AppDelegate appDel = (AppDelegate)UIApplication.SharedApplication.Delegate;
// I added this InvokeOnMainThread to see if it would solve the "data out of order problem", but it didn't
appDel.InvokeOnMainThread (delegate{
Console.WriteLine("ReceiveCallback IsMainThread = " + NSThread.IsMain);
try {
// Retrieve the state object and the client socket
// from the asynchronous state object.
StateObject state = (StateObject) ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0) {
// There might be more data, so store the data received so far.
string stuffWeReceived = Encoding.ASCII.GetString(state.buffer,0,bytesRead);
string debugString = "~~ReceiveCallback~~ len = " + stuffWeReceived.Length + " bytesRead = " + bytesRead + ": " + stuffWeReceived;
if ( appDel.diagnosticsScreen.DebugAsyncReceiveBuffer_Switch.On )
{
appDel.diagnosticsScreen.AppendToDebugLog(debugString);
}
Console.WriteLine(debugString);
// Send this data to be received
appDel.wallInteractionScreen.ChitterChatter.ReceiveSomeData(stuffWeReceived);
// Get the rest of the data.
client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,
new AsyncCallback(ReceiveCallback), state);
} else {
// Signal that all bytes have been received.
receiveDone.Set();
}
}
catch (Exception e) {
Console.WriteLine("Error in AsyncClient ReceiveCallback: ");
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
});
}
This ended up being a Threading/Locking problem in my code on the C# side. I rewrote my locking mechanisms from scratch and now have things working 100% of the time. Thanks to everyone who helped me see this one through!
这篇关于异步客户端套接字,无序接收缓冲区数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!