Sockets.Connected总是如此?

时间:2012-04-25 15:55:03

标签: c# sockets

我有一个使用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));
            } 
        }
    }

1 个答案:

答案 0 :(得分:0)

您永远不应该(必须)依赖常规程序流的异常。

当客户端关闭套接字时,服务器将收到一个0字节的数据包,并在您调用Receive时继续接收该数据包。这会导致你的while循环永远持续下去。您应该处理count为0的情况,并将其视为客户端关闭的常规“连接”。 如果客户端无法正常关闭,则只会出现您提到的异常。