我有一个客户端应用程序,它使用TcpClient
将文件发送到使用TcpListener
接收它的服务器应用程序。有时,文件传输正常。但在其他时候,转移开始但没有完成。在服务器上读取了不同数量的字节后,我收到一条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图像,即使连接速度最慢,传输的时间也不会超过两秒。更改客户端和侦听器的超时值无济于事。