我有一些非常简单的代码,它从连接到的网络流中读取行。在代码示例中,每次只读取一行,并且不会从服务器获取更多内容。
有什么问题?
byte[] readBuffer = new byte[1024];
byte[] tempBuff = new byte[1024];
int tempBuffSize = 0;
private void btnConnect_Click(object sender, EventArgs e)
{
TcpClient tcpClient = new TcpClient("192.168.1.151", 5505);
NetworkStream stream = tcpClient.GetStream();
stream.BeginRead(readBuffer, 0, 1024, readHandler, tcpClient);
}
void readHandler(IAsyncResult result)
{
TcpClient tcpClient = (TcpClient)result.AsyncState;
int dataLen = tcpClient.GetStream().EndRead(result);
int currStart = 0;
int currEnd = -1;
for (int i = 0; i < dataLen; i++)
{
if (readBuffer[i] == '\r' && i < (readBuffer.Length - 1) &&
readBuffer[i + 1] == '\n')
{
// Set the end of the data
currEnd = i - 1;
// If we have left overs from previous runs:
if (tempBuffSize != 0)
{
byte[] joinedData = new byte[tempBuffSize + (currEnd - currStart + 1)];
Array.Copy(tempBuff, 0, joinedData, 0, tempBuffSize);
Array.Copy(readBuffer, currStart, joinedData, tempBuffSize, (currEnd - currStart + 1));
System.Text.Encoding enc = System.Text.Encoding.ASCII;
string myString = enc.GetString(joinedData);
System.Diagnostics.Debug.Write(myString);
tempBuffSize = 0;
}
else
{
System.Text.Encoding enc = System.Text.Encoding.ASCII;
string myString = enc.GetString(readBuffer);
System.Diagnostics.Debug.Write(myString);
// HandleData(readBuffer, currStart, currEnd);
}
// Set the new start - after our delimiter
currStart = i + 2;
}
}
// See if we still have any leftovers
if (currStart < dataLen)
{
Array.Copy(readBuffer, currStart, tempBuff, 0, dataLen - currStart);
tempBuffSize = dataLen - currStart;
}
}
答案 0 :(得分:2)
为什么您希望它首先阅读整个信息?我不是专家,但在我看来,同步或异步方法都不能保证读取所有数据(无论这意味着什么,因为只要一个套接字打开,就会有更多的数据到达)。在EndRead方法中的代码之后,如果您需要更多数据,则应再次调用Read或BeginRead。根据您与客户建立的协议,您应该知道是否需要更多数据。
答案 1 :(得分:1)
当我为嵌入式设备开发tcp应用程序时,我遇到了类似的问题。在我的情况下,问题是设备在延迟的时间内发出数据,因此在其余数据进入控制之前移动到程序中的下一行,只从服务器获取初始数据。我通过引入延迟解决了这个问题。
在您从服务器读取数据的行之后引入延迟,因此最好在单独的线程上运行它
thread.sleep(3000)
这很可能是你的问题。
答案 2 :(得分:0)
也许你的流对象在超出范围时就被处理掉了,然后才能再次调用readHandler。尝试提升tcpClient并流式传输到类范围而不是方法范围,或者将读取移动到操作完成时退出的单独线程。