TcpListener正在随机截断字节数组
本文关键字:字节 字节数 数组 随机 TcpListener | 更新日期: 2023-09-27 18:27:34
我正在编写一个本质上是用于存储图像的图像备份服务器。它是一种单向服务,除了基本的成功或失败消息之外,不会向客户端返回任何信息。
我遇到的问题是,当我通过网络流发送字节数组时,它在流结束前的随机位置被截断。当我在开发机器上运行服务器并进行本地连接时,我没有这个问题,但只有当服务器部署在远程服务器上时才会出现这个问题。
当我发送非常小的数组(<512字节)时,服务器会成功接收整个流,但在大于2000字节的流上,我会遇到问题。客户端的代码如下:
try
{
TcpClient Voice = new System.Net.Sockets.TcpClient();
//Obviously I use the remote IP when it is deployed - but have altered it for privacy.
IPEndPoint BackupServer = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 57000);
Voice.Connect(BackupServer);
NetworkStream DataStream = Voice.GetStream();
byte[] buffer = new ASCIIEncoding().GetBytes(ImageData.GetXml());
DataStream.Write(buffer, 0, buffer.Length);
DataStream.Flush();
}
catch
{
}
try
{
buffer = new byte[4096];
int read = DataStream.Read(buffer, 0, buffer.Length);
MessageBox.Show(new ASCIIEncoding().GetString(buffer) + " : " + read.ToString());
}
catch
{
}
无论我发送的数据大小如何,客户端代码都不会出现任何错误或问题。
服务器端的代码如下:
private void BackMeUp(object voice)
{
TcpClient Voice = (TcpClient)voice;
Voice.ReceiveTimeout = 30000;
NetworkStream DataStream = Voice.GetStream();
try
{
bool ShouldLoop = true;
//int loops = 0;
int loops = -1;
byte[] input = new byte[2048];
byte[] buffer = new byte[0];
//while (ShouldLoop)
while(loops != 0)
{
loops = DataStream.Read(input, 0, 2048);
for (int x = 0; x < loops; x++)
{
Array.Resize(ref buffer, buffer.Length + 1);
buffer[buffer.Length - 1] = input[x];
}
//if (loops < 2048)
//{
//ShouldLoop = false;
//break;
//}
}
while (true)
{
StringReader Reader = new StringReader(new ASCIIEncoding().GetString(buffer, 0, buffer.Length));
DataSet DS = new DataSet();
DS.ReadXml(Reader);
if (DS.Tables.Count > 0)
{
if (DS.Tables["Images"].Rows.Count > 0)
{
foreach (DataRow row in DS.Tables["Images"].Rows)
{
//
}
}
}
string response = "Got it!";
DataStream.Write(new ASCIIEncoding().GetBytes(response), 0, response.Length);
DataStream.Flush();
Voice.Close();
break;
}
}
catch (Exception Ex)
{
File.WriteAllText("Elog.txt", Ex.Message + " " + (Ex.InnerException != null ? Ex.InnerException.ToString() : " no Inner"));
Voice.Close();
}
}
服务器会很好地接收数据,并在数据流到达末尾时关闭数据流,但是数据被截断,并且在尝试重建数据集时出错。
我觉得这与发送流所需的时间有关,我也玩过Close和Flush命令,但我觉得我只是在黑暗中拍摄。如有任何帮助,我们将不胜感激。
问题的简明版本:TcpListener涉及哪些因素,可能导致a)流的截断。或b)在读取所有字节之前过早地关闭流。当有问题的侦听器位于远程主机而不是本地服务器上时。
Read
方法不必同时返回请求的字节数或整个流。特别是如果流很慢,它将以小块的形式返回。
重复调用Read
方法,并处理您获得的每个块的数据。当流被读取到最后时,Read
方法返回零:
buffer = new byte[4096];
do {
int read = DataStream.Read(buffer, 0, buffer.Length);
if (read != 0) {
// handle the first "read" bytes of the buffer (index 0 to read-1)
}
} while (read != 0);
如果你知道你的缓冲区足以容纳任何流,你可以填满缓冲区,然后再处理:
buffer = new byte[4096];
int offset = 0;
do {
int read = DataStream.Read(buffer, offset, buffer.Length - offset);
offset += read;
} while (read != 0);
// handle the first "offset" bytes of the buffer (index 0 to offset-1)