首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Sockets.Connected总是真的吗?

Sockets.Connected总是真的吗?
EN

Stack Overflow用户
提问于 2012-04-25 15:55:02
回答 1查看 1.6K关注 0票数 0

我有一个使用WCF服务的小文件传输应用程序,它通过tcp套接字发送文件和文件夹。

我的问题是,当我从客户端取消传输操作(后台工作人员)时,服务器仍然在client.Receive上冻结,它假设给我一个例外:An existing connection was forcibly closed by the remote host,但它没有,尽管在客户端,socket.Connected变成了falsesocket.Connected变成了false

我需要得到这个异常并处理它,这样我就可以关闭流和套接字,并准备好接收另一个任务!

客户端:

代码语言:javascript
复制
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));
            } 
        }
    }

服务器端:

代码语言:javascript
复制
public void ConnectToClient(IPEndPoint endpoint)
    {
        if (client == null)
        {
            Thread th = new Thread(unused => ConnectTh(endpoint));
            th.Start();
        }
    }
    private void ConnectTh(IPEndPoint endpoint)
    {
        client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        client.Connect(IPAddress.Parse("127.0.0.1"), endpoint.Port);
    }


public void ReceiveFile(_File file, int bufferSize)
    {
        System.Threading.Thread th = new System.Threading.Thread(unused => ReceiveX(client, file.Name, file.Size, bufferSize));
        th.Start();
    }

private void ReceiveX(Socket client, string destPath, long size, int bufferSize)
    {
        try
        {
            using (Stream stream = File.Create(destPath))
            {
                byte[] buffer = new byte[bufferSize];
                long sum = 0;
                int count = 0;
                while (sum < size)
                {
                    int bytesToReceive = (int)Math.Min(buffer.Length, size - sum);
                    count = client.Receive(buffer, 0, bytesToReceive, SocketFlags.None);
                    stream.Write(buffer, 0, count);
                    sum += count;
                }
            }
        }
        catch
        {
            if (File.Exists(destPath))
                File.Delete(destPath);
            client.Dispose();
        }
    }
EN

Stack Overflow用户

回答已采纳

发布于 2012-04-25 18:08:08

对于常规程序流,您永远不应该(不得不)依赖异常。

当客户端关闭套接字时,服务器将接收0字节的数据包,并在调用Receive时继续接收该数据包。这将导致while循环永久持续。您应该处理count为0的情况,并将其视为一个常规的“客户端关闭的连接”。您提到的异常仅在客户端无法正确关闭时才会发生。

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10319244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档