客户端断开连接或关闭

Client Dissconnect or down

我在 visual studio Windows Forms App(.Net Framework 4) 中有 2 个应用程序我的两个程序的名称是:

IpServer

IpClient

我的问题是,当 IpClient 应用程序关闭或停止或 IpServer 应用程序在 messagebox.show("Client Is dissconnect")

中显示一条消息时,我不知道该怎么做

IP服务器代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;

namespace IpServer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        TcpListener tcplist;
        Socket s;
        private void init()
        {
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            tcplist = new TcpListener(ip,5050);
            tcplist.Start();
            while (true)
            {
                s = tcplist.AcceptSocket();
                Thread t = new Thread(new ThreadStart(replay));
                t.IsBackground = true;
                t.Start();
            }
        }
        private void replay()
        {
            Socket sc = s;
            NetworkStream ns = new NetworkStream(sc);
            StreamReader reader = new StreamReader(ns);
            StreamWriter writer = new StreamWriter(ns);
            string str = "";
            string response = "";
            try { str = reader.ReadLine(); }
            catch { str = "error"; }
            if (str == "register")
            {
                MessageBox.Show("ok");
            }
            response = "registeredSucss,";
            writer.WriteLine(response);
            writer.Flush();
            ns.Close();
            sc.Close();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(init));
            t.IsBackground = true;
            t.Start();
            MessageBox.Show("Server run!!");
            button1.Enabled = false;
        }

和 IpClient 代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace IpClient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        TcpClient tcp;
        NetworkStream ns;
        StreamReader reader;
        StreamWriter writer;
        string str = "";

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                tcp = new TcpClient("127.0.0.1",5050);
                tcp.ReceiveBufferSize = 25000;
                tcp.NoDelay = true;
                ns = tcp.GetStream();
                reader = new StreamReader(ns);
                writer = new StreamWriter(ns);
                writer.WriteLine("register");
                writer.Flush();
                str = reader.ReadLine();
                string[] strsplit = null;
                strsplit = str.Split(',');
                if (strsplit[0] != "registeredSucss")
                {
                    MessageBox.Show("Not connected");
                }
                else
                {
                    MessageBox.Show("Your connected");
                }
                
            }
            catch
            {
                MessageBox.Show("error");
            }
        }

我写了一个完整的例子给你。

您可以根据需要进行修改。

不发送或接收消息,仅将客户端连接到服务器不会断开连接。

在server和client中,有一个线程不断调用receive函数,在连接断开时发送消息

 byte[] buffer = new byte[1024 * 1024 * 2];
                    int length = socket.Receive(buffer);
                    if (length == 0) {
                    ///Write the desired operation
                    }

“关闭 window 时断开连接”使用 formclosing 事件:

 private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
        }

这是两人使用的控制图windows:

IpClient:

IpServe:

这是两个windows的代码:

IpClient:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace IpClient {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }
        Socket socket;//The socket responsible for the connection
        private void ConnectB_Click(object sender, EventArgs e) {
            //Determine whether to request a connection repeatedly
            try {
                Log("Connected " + socket.LocalEndPoint.ToString() + "\nPlease do not request the connection repeatedly");
            } catch {
                //Determine whether the input is wrong
                try {
                    socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    //Create IP address and port number;
                    IPAddress ip = IPAddress.Parse(Ipbox.Text);
                    int port = Convert.ToInt32(PortBox.Text);
                    IPEndPoint iPEndPoint = new IPEndPoint(ip, port);
                    //Determine whether you can connect to the server
                    try {
                        socket.Connect(iPEndPoint);
                        Log("Connected " + socket.LocalEndPoint.ToString());
                        //Start receiving data thread
                        Thread th = new Thread(receive);
                        th.IsBackground = true;
                        th.Start();
                    } catch {
                        Log("Port is not open");
                    }                  
                } catch  {
                    socket = null;
                    Log("Input error");
                }
            }
        }

        private void Log(string str) {
            ClientLog.AppendText(str + "\r\n");
        }
        private void receive() {
            while (true) {
                //Determine whether the data can be received
                try {
                    byte[] buffer = new byte[1024 * 1024 * 2];
                    int length = socket.Receive(buffer);
                    if (length == 0) {
                        Log("Port is not open");
                        CloseSocket(socket);
                        socket = null;
                        break;
                    }
                    string txt = Encoding.UTF8.GetString(buffer, 0, length);
                    Log(socket.RemoteEndPoint + ":\r\t" + txt);
                } catch {
                    break;
                }
            }
        }

        private void Form1_Load(object sender, EventArgs e) {
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void CloseB_Click(object sender, EventArgs e) {
            if (socket != null) {
                CloseSocket(socket);
                socket = null;
                Log("Connection closed");
                
            } else {
                Log("Not connected");
            }
        }

        private void SendB_Click(object sender, EventArgs e) {
            try {
                string txt = SendText.Text;
                byte[] buffer = Encoding.ASCII.GetBytes(txt);//ascii encoding
                socket.Send(buffer);
            } catch {
                Log("Not connected");
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
            if (socket != null) {
                CloseSocket(socket);
                socket = null;
            }
        }

        //Disconnect socket
        private void CloseSocket(Socket o) {
            try {
                o.Shutdown(SocketShutdown.Both);
                o.Disconnect(false);
                o.Close();
            } catch {
                Log("error");
            }
        }
    }
}

IP服务器:

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace IpServer {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }
        Socket socketSend;//Socket responsible for communication
        Socket socketListener;//Socket responsible for monitoring
        Dictionary<string, Socket> dictionary = new Dictionary<string, Socket>();//Store the connected Socket
        private void listnerB_Click(object sender, EventArgs e) {
            //Create a listening socket
            //SocketType.Stream streaming corresponds to the tcp protocol
            //Dgram, datagram corresponds to UDP protocol
            socketListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try {
                //Create IP address and port number;
                IPAddress ip = IPAddress.Parse(Ipbox.Text);
                int port = Convert.ToInt32(PortBox.Text);
                IPEndPoint iPEndPoint = new IPEndPoint(ip, port);
                //Let the listening socket bind the ip and port number
                socketListener.Bind(iPEndPoint);
                Log("Listen successfully" + ip + "\t" + port);
                //Set up the listening queue
                socketListener.Listen(10);//Maximum number of connections at a time
                Thread thread = new Thread(Listen);
                thread.IsBackground = true;
                thread.Start(socketListener);
        } catch  {
                Log("Failed to listen");
    }
}

        //Use threads to receive data
        private void Listen(object o) {
            Socket socket = o as Socket;
            while (true) {
                //The socket responsible for monitoring is used to receive client connections
                try {
                    //Create a socket responsible for communication
                    socketSend = socket.Accept();
                    dictionary.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
                    clientCombo.Items.Add(socketSend.RemoteEndPoint.ToString());
                    clientCombo.SelectedIndex = clientCombo.Items.IndexOf(socketSend.RemoteEndPoint.ToString());
                    Log("Connected " + socketSend.RemoteEndPoint.ToString());
                    //Start a new thread to receive information from the client
                    Thread th = new Thread(receive);
                    th.IsBackground = true;
                    th.Start(socketSend);
                } catch  {
                    continue;
                }        
            }           
        }

        //The server receives the message from the client
        private void receive(object o) {
            Socket socketSend = o as Socket;
            while (true) {
                //Try to connect to the client
                try {
                    //After the client connects successfully, the server receives the message from the client
                    byte[] buffer = new byte[1024 * 1024 * 2];//2M大小
                     //Number of valid bytes received
                    int length = socketSend.Receive(buffer);
                    if (length == 0) {
                        string tmpIp = socketSend.RemoteEndPoint.ToString();
                        Log(tmpIp + " Offline");
                        clientCombo.Items.Remove(tmpIp);
                        //Try to delete the connection information
                        try {
                            clientCombo.SelectedIndex = 0;
                        } catch  {
                            clientCombo.Text = null;
                        }
                        CloseSocket(dictionary[tmpIp]);
                        dictionary.Remove(tmpIp);                        
                        break;
                    }
                    string str = Encoding.ASCII.GetString(buffer, 0, length);
                    Log(socketSend.RemoteEndPoint.ToString() + "\n\t" + str);
                } catch {           
                    break;
                }
            }
        }

        private void Log(string str) {
            ServerLog.AppendText(str + "\r\n");
        }

        private void Form1_Load(object sender, EventArgs e) {
            //Cancel errors caused by cross-thread calls
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        //Send a message
        private void SendB_Click(object sender, EventArgs e) {
            string txt = SendText.Text;
            byte[] buffer = Encoding.UTF8.GetBytes(txt);
            try {
                string ip = clientCombo.SelectedItem.ToString();//Get the selected ip address
                Socket socketsend = dictionary[ip];
                socketsend.Send(buffer);
            } catch{
                Log("Transmission failed");
            }
        }

        private void Close_Click(object sender, EventArgs e) {
            try {
                try {
                    string tmpip = socketSend.RemoteEndPoint.ToString();                    
                    CloseSocket(dictionary[tmpip]);
                    dictionary.Remove(tmpip);
                    clientCombo.Items.Remove(tmpip);
                    try {
                        clientCombo.SelectedIndex = 0;
                    } catch {
                        clientCombo.Text = null;
                    }
                    socketSend.Close();
                    Log(socketSend.RemoteEndPoint.ToString() + "Offline");
                    socketListener.Close();
                    Log("Listener is closed");
                } catch{
                    socketListener.Close();
                    Log("Listener is closed");
                }                            
            } catch {
                Log("close error");
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
            try {
                try {
                    string tmpip = socketSend.RemoteEndPoint.ToString();
                    CloseSocket(dictionary[tmpip]);
                    dictionary.Remove(tmpip);
                    clientCombo.Items.Remove(tmpip);
                    try {
                        clientCombo.SelectedIndex = 0;
                    } catch {
                        clientCombo.Text = null;
                    }
                    socketSend.Close();
                    socketListener.Close();
                } catch {
                    socketListener.Close();
                }
            } catch {
            }
        }

        private void CloseSocket(Socket o) {
            try {
                o.Shutdown(SocketShutdown.Both);
                o.Disconnect(false);
                o.Close();
            } catch  {
                Log(o.ToString() + "error");
            }           
        }
    }
}

输出:

关闭 window 导致断开连接:

手动断开:

传输数据:

如果您对我的代码有任何疑问,请在下面添加评论。