我有一个使用WCF服务的小文件传输应用程序,它通过tcp套接字发送文件和文件夹。
我的问题是,当我从客户端取消传输操作(backgroundworker)时,服务器仍在client.Receive
冻结,它假设给我这个例外:An existing connection was forcibly closed by the remote host
,但它没有,尽管在客户端, listener.Connected 变为{{ 1}}和 socket.Connected 变为false
我需要获取此异常并处理它,以便我可以关闭流和套接字并准备接收另一个任务!
客户端:
false
服务器端:
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
List<Job> Jobs = (List<Job>)e.Argument;
using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 0);
listener.Bind(endpoint);
listener.Listen(1);
client.ConnectToClient((IPEndPoint)listener.LocalEndPoint);
Socket socket = listener.Accept();
foreach (Job job in Jobs)
{
if (job.IsFile)
{
if (job.IsSend)
{ SendFile(socket, job, e); } //here i send a single file.
// else
// { ReceiveFile(socket, job, e); }
}
// else
// {
// if (job.IsSend)
// { SendDir(socket, job, e); }
// else
// { ReceiveDir(socket, job, e); }
// }
if (worker.CancellationPending)
{
e.Cancel = true;
socket.Dispose();
listener.Dispose();
Console.WriteLine(socket.Connected + " " + listener.Connected);
//it prints "FALSE FALSE"
return;
}
}
}
}
private void SendFile(Socket socket, Job job, DoWorkEventArgs e)
{
UpdateInfo(job.Name, job.Icon); //update GUI with file icon and name.
client.ReceiveFile((_File)job.Argument, bufferSize); //tell the client to start receiving
SendX(socket, ((_File)job.Argument).Path, e); //start sending..
}
private void SendX(Socket socket, string filePath, DoWorkEventArgs e)
{
using (Stream stream = File.OpenRead(filePath))
{
byte[] buffer = new byte[bufferSize];
long sum = 0;
int count = 0;
while (sum < stream.Length)
{
if (worker.CancellationPending)
{
e.Cancel = true;
return;
}
count = stream.Read(buffer, 0, buffer.Length);
socket.Send(buffer, 0, count, SocketFlags.None);
sum += count;
SumAll += count;
worker.ReportProgress((int)((sum * 100) / stream.Length));
}
}
}
答案 0 :(得分:0)
您永远不应该(必须)依赖常规程序流的异常。
当客户端关闭套接字时,服务器将收到一个0字节的数据包,并在您调用Receive
时继续接收该数据包。这会导致你的while循环永远持续下去。您应该处理count
为0的情况,并将其视为客户端关闭的常规“连接”。
如果客户端无法正常关闭,则只会出现您提到的异常。