C#现有的连接被远程主机强行关闭:套接字编程 [英] C# An existing connection was forcibly closed by the remote host: socket programming

查看:167
本文介绍了C#现有的连接被远程主机强行关闭:套接字编程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用套接字。这是我的代码(对问题的描述进一步):

I am working with sockets. Here are my codes (the description of problem is further):

客户端

    public void ReadCallback(IAsyncResult ar)
    {
        int fileNameLen = 1;
        String content = String.Empty;
        StateObject state = (StateObject)ar.AsyncState;
        Socket handler = state.workSocket;

        int bytesRead = handler.EndReceive(ar);
        if (bytesRead > 0)
        {

            if (flag == 0)
            {

                fileNameLen = BitConverter.ToInt32(state.buffer, 0);
                string fileName = Encoding.UTF8.GetString(state.buffer, 4, fileNameLen);
                receivedPath = mypath + @"XML\";
                if (!Directory.Exists(receivedPath))
                {
                    Directory.CreateDirectory(receivedPath);
                }
                receivedPath = receivedPath + fileName;
                flag++;

            }
            if (flag >= 1)
            {

                BinaryWriter writer = new BinaryWriter(File.Open(receivedPath, FileMode.Append));
                if (flag == 1)
                {
                    writer.Write(state.buffer, 4 + fileNameLen, bytesRead - (4 + fileNameLen));
                    flag++;
                }
                else
                    writer.Write(state.buffer, 0, bytesRead);
                writer.Close();
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReadCallback), state);
            }

        }
        else
        {
            //   Invoke(new MyDelegate(LabelWriter));
        }
    }

我在这行出现错误: int bytesRead = handler.EndReceive(ar);

如何避免此错误?:一个现有的连接被远程主机强行关闭

服务器端

        public void ReadCallback(IAsyncResult ar)
        {
            try
            {

                int fileNameLen = 1;
                String content = String.Empty;
                StateObject state = (StateObject)ar.AsyncState;
                Socket handler = state.workSocket;
                string[] str = new string[2];
                str = handler.RemoteEndPoint.ToString().Split(':');
                IP = str[0].ToString();
                int bytesRead = handler.EndReceive(ar);

                if (bytesRead > 0)
                {
                    if (flag == 0)
                    {
                        fileNameLen = BitConverter.ToInt32(state.buffer, 0);
                        string fileName = Encoding.UTF8.GetString(state.buffer, 4, fileNameLen);
                        string[] getIP = new string[3];
                        getIP = fileName.Split('_');
                        #region Send Files in HandHeld
                        #region GetLoginFile
                        if (getIP[1].ToString().Equals("GetLoginFile"))
                        {
                            string getDirectory = @"Send_Hand_Held_Files\" + DateTime.Today.ToString("dd-MM-yyyy") + "\\" + getIP[0].ToString() + "\\XML";
                            string strmyFile = getDirectory + "\\Login.xml";
                            char[] delimiter = splitter.ToCharArray();
                            split = strmyFile.Split(delimiter);
                            int limit = split.Length;
                            fName = split[limit - 1].ToString();

                            byte[] LoginfileName = Encoding.UTF8.GetBytes(fName); //file name

                            byte[] fileData = File.ReadAllBytes(strmyFile);

                            byte[] LoginfileNameLen = BitConverter.GetBytes(LoginfileName.Length); //lenght of file name
                            clientData = new byte[4 + LoginfileName.Length + fileData.Length];

                            LoginfileNameLen.CopyTo(clientData, 0);
                            LoginfileName.CopyTo(clientData, 4);
                            fileData.CopyTo(clientData, 4 + LoginfileName.Length);

                            handler.BeginSend(clientData, 0, clientData.Length, 0, new AsyncCallback(SendCallBack), handler);
                            //handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                            //new AsyncCallback(ReadCallback), state);
                            return;
                        }
 }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);

            }
            //SendData(IP);
        }

     private static void SendCallBack(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object.
                Socket client = (Socket)ar.AsyncState;

                // Complete sending the data to the remote device.
               // int bytesSent = client.EndSend(ar);
                //Console.WriteLine("Sent {0} bytes to server.", bytesSent);

                // Signal that all bytes have been sent.
                allDone.Set();

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }


推荐答案

您从 handler.EndReceive()获取异常。可以肯定的是,为什么并没有收到您提到的特定异常,但是当投入生产时,此代码 会在每次出现网络通信问题时抛出异常(这是

You are getting an exception from handler.EndReceive(). While admittedly it is unclear why you’re receiving the specific exception you mentioned, when put into production this code will throw exceptions every time there is a network communication problem (which is common).

因此,您可能应该尝试对 EndReceive()的调用进行尝试/捕获。考虑一下一旦连接失败或服务器死机或其他原因,您的代码将需要做什么。

Therefore, you should probably put a try/catch around the call to EndReceive() anyway. Think about what your code would need to do whenever the connection fails or the server dies or whatever.

然后,您可以开始诊断特定的问题。您尚未指定的一件重要事情:您是仅偶尔 收到此错误,还是始终可重复地得到此错误?如果是前者,则可能只是正常的Internet连接波动。您的软件必须能够处理这些问题。如果是后者,那么我认为这听起来像是服务器上的问题。当您调用 BeginReceive()时,系统将开始等待服务器中的某些内容。如果该东西是它接收到的数据,则 EndReceive()将成功,但是如果该东西是服务器关闭了连接,您的回调仍将被调用,然后 EndReceive()将引发相关的 SocketException 。这是设计使然,因为几乎没有其他方法可以与您的代码进行通信,表明服务器已关闭连接。

Then you can start diagnosing specific problems. One important thing you haven’t specified: do you get this error only occasionally or do you reproducibly get it all the time? If it’s the former, then it might just be normal Internet connectivity fluctuations. Your software will have to be able to handle those. If it’s the latter, then I think it sounds like a problem on the server. When you call BeginReceive(), your system will start waiting for something from the server; if that "something" is that it received data, then EndReceive() will succeed, but if that "something" is that the server has closed the connection, your callback will still be invoked, and then EndReceive() will throw the relevant SocketException. This is by design because there’s pretty much no other way to communicate to your code that the server has closed the connection.

编辑:您的服务器代码需要相同的错误处理:如果 client 关闭连接,则对 EndReceive()的调用同样容易引发异常。 (我知道您可以尝试/抓住整个大问题,但是它会输出一个 MessageBox ...在服务器上无法正常工作,除非您希望有人一直坐在那里单击所有的确定按钮...)

Looks like your server code needs the same error handling: its call to EndReceive() is equally prone to throwing an exception if the client closes the connection. (I know you have a try/catch around the whole big thing, but it outputs a MessageBox... that is not going to work well on a server, unless you want someone sitting there all the time clicking on all the OK buttons...)

这篇关于C#现有的连接被远程主机强行关闭:套接字编程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆