我有一个客户端应用程序,它使用 aTcpClient
将文件发送到使用 aTcpListener
接收它的服务器应用程序。有时,文件传输正常。但在其他时候,传输开始但没有完成。在服务器上读取不同数量的字节后,我收到一个 IOException 消息:“现有连接被远程主机强行关闭。”
在客户端,我创建了一个头字节数组,其中包含有关我的文件的数据,包括以字节为单位的总大小和其他一些数据位。我将此字节数组与文件的字节数组结合起来,并将其发送到服务器。
TcpClient fileClient = new TcpClient();
fileClient.Connect("mydomain.com", 7728);
NetworkStream clientStream = fileClient.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
FileStream fs = File.Open(filePath, FileMode.Open);
string header = filePath + "|" + fs.Length.ToString() + "|" + this.ID); //ID = short string of mine
header = header.PadRight(512, '*');
byte[] sizeArray = encoder.GetBytes(header);
byte[] fileBuffer = new byte[fs.Length];
fs.Read(fileBuffer, 0, Convert.ToInt32(fs.Length));
fs.Close();
byte[] buffer = Combine(sizeArray, fileBuffer); //Combine = method I use to combine byte arrays
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
在服务器端,我创建了一个TcpListener
,然后开始收听。当我得到一个连接时,我处理它,读取我的头数组,前 512 个字节,确定新文件的大小,然后使用此代码读取文件/其余字节:
int newSize = ... //The size that I sent in my header array
byte[] fileArray = new byte[newSize];
int off = 0;
while (true)
{
try
{
off += clientStream.Read(fileArray, off, fileArray.Length - off);
}
catch (Exception ex)
{
off = newSize; // Enables partial receive on error, not total loss
}
if (off >= newSize)
{
break;
}
}
这就是有时——大约 25% 的时间——出错的地方。我会off += clientStream.Read(fileArray, off, fileArray.Length - off)
在线上得到例外。我用 try catch 包围它,即使发生此错误,应用程序仍能获取文件的一部分。但是,我需要能够一直获取完整的文件。我对这段代码做错了什么?
我正在传输的文件是大小约为 100KB 的 JPEG 图像,即使在最慢的连接上传输通常也不会超过两秒钟。更改客户端和侦听器的超时值无济于事。