现有连接被远程主机强行关闭

时间:2019-08-07 08:07:46

标签: c# sockets

我的C#Windows窗体的一部分是对等(仅两个用户)聊天。 我使用.Net套接字。

我想做的是,只要有两个用户都可以聊天,他们就可以聊天。但是,当其中一个关闭程序然后再次打开它时,会出现许多问题。或者只有一个人在线时,我会收到此异常。

“远程主机强行关闭了现有连接。”

我尝试使用Socket.Close和Socket.ShutDown。我还尝试通过再次定义它来重新初始化套接字变量。一切似乎都行不通。我愿意接受任何建议,甚至可以使用不同的库或方法。

代码如下:

namespace TextChatApp
{
    public partial class Form1 : Form

    {
        //attributes:
        Socket sck;
        EndPoint epLocal, epRemote;



        public Form1()
        {
            InitializeComponent();
            sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            sck.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

            textBox1.Text=GetLocalIP();
            textBox3.Text = GetLocalIP();
            textBox2.Text = "8001";
            textBox4.Text = "8000";
            send.Enabled = false;
            connectEndPoint();
            InitTimer();
        }

        private void MessageCallBack(IAsyncResult aResult)
        {
            try
            {
                int size = sck.EndReceiveFrom(aResult, ref epRemote);
                if(size>0)
                {
                    byte[] receivedData = new byte[1500];
                    receivedData = (byte[])aResult.AsyncState;
                    ASCIIEncoding eEncoding = new ASCIIEncoding();
                    string receivedMessage = eEncoding.GetString(receivedData);
                    listBox1.Items.Add("From a friend: "+receivedMessage);
                }
                byte[] buffer = new byte[1500];
                sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer);

            }
            catch(Exception exp)
            {
                MessageBox.Show("Exception Small Chat: " + exp.ToString());
            }
        }

        private void start_Click(object sender, EventArgs e)
        {

        }

        public void connectEndPoint()
        {
            try
            {
                epLocal = new IPEndPoint(IPAddress.Parse(textBox1.Text), Convert.ToInt32(textBox2.Text));
                sck.Bind(epLocal);

                epRemote = new IPEndPoint(IPAddress.Parse(textBox3.Text), Convert.ToInt32(textBox4.Text));
                sck.Connect(epRemote);

                byte[] buffer = new byte[1500];
                sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer);
                start.Enabled = false;
                start.Text = "Connected";
                send.Enabled = true;
                textBox5.Focus();

            }
            catch (Exception exp)
            {

            }
        }

        private void send_Click(object sender, EventArgs e)
        {
            try
            {
                System.Text.Encoding encoding = System.Text.Encoding.UTF8;
                byte[] msg = new byte[1500];
                msg = encoding.GetBytes(textBox5.Text);//

                sck.Send(msg);
                listBox1.Items.Add("You: " + textBox5.Text);
                textBox5.Clear();
            }
            catch(Exception exp)
            {
                MessageBox.Show("Exception Small Chat: " + exp.ToString());
            }
        }

1 个答案:

答案 0 :(得分:0)

我想我解决了自己的问题。 由于在发送数据时触发了异常,并且端点已关闭或未连接,因此我应该在发送数据之前检查它是否已连接。

但是,没有直接的方法可以找到端点是否已连接。 由于当我发送数据且端点处于关闭状态时会触发异常,因此该异常成为我指示端点处于关闭状态且连接断开的指示器。因此,我要做的是在“ Catch”语句中再次创建Socket,然后每隔一段时间重试一次,直到再次连接Socket。

每次触发异常时,我再次创建Socket的原因是因为Socket不稳定,并且会导致许多连接问题。因此,最好重新创建它,而不要不稳定。

这是我包含的代码

               private void MessageCallBack(IAsyncResult aResult)
                {  
                 try
                {
                    int size = sck.EndReceiveFrom(aResult, ref epRemote);
                    if(size>0)
                    {
                        byte[] receivedData = new byte[1500];
                        receivedData = (byte[])aResult.AsyncState;
                        ASCIIEncoding eEncoding = new ASCIIEncoding();
                        string receivedMessage = eEncoding.GetString(receivedData);
                        listBox1.Invoke(new MethodInvoker(delegate { 
                    listBox1.Items.Add("From a friend: " + receivedMessage); }));
                    }
                    byte[] buffer = new byte[1500];
                    sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, 
                ref epRemote, new AsyncCallback(MessageCallBack), buffer);

                }
                catch(Exception exp)
                { /* here is the solution, when the Catch is triggered, close the 
                  socket and recreate it to avoid the issues that I been having of 
                  not sending messages and instability. I also added some functions 
                  that would keep sending the status and //being checked on the other 
                  side in order to keep online/offline status.*/

                    sck.Close();
                    sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 
                     ProtocolType.Udp);
                    sck.SetSocketOption(SocketOptionLevel.Socket, 
                     SocketOptionName.ReuseAddress, true);
                    connectEndPoint();
                    //MessageBox.Show("Exception Small Chat: " + exp.ToString());
                }
    }