preface
At this time, I understand a word called long connection and short connection
Long connection means to declare an event and then open the operation... And then close it. This is a long connection. The long connection can only be opened at the beginning and closed at the end. It can send what data it wants to send and receive what data it wants to receive,
Short connection means that every time you receive or send, you have to turn it on or off. For example, when you send, you need to turn it on, turn it off, turn it on, and turn it off
Both long and short connections are used in different situations
tcp connection is a long connection, but if the connection time is too long and there is no data, the system may think that the connection has been disconnected or disconnect it for you by default
Therefore, in the long connection, we also need to achieve the heartbeat mechanism and send heartbeat packets periodically. Why is it called heartbeat packets
I think it may be because of periodicity, and everyone's heartbeat is different, and everyone defines the content and cycle of heartbeat package differently
So it's called heartbeat
This can be achieved in time and space
Next, I use dictionary socket to classify
So that tcp can receive data from multiple ports at the same time and can choose the port to send data
Add the previous heartbeat mechanism
Get the ip ports of all clients connected to the server every heartbeat
If you want to send data to anyone, add ip and port to the sent data
When the data is received by the server, the communication between two clients or multiple clients is completed
Server end final program
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace Server { public partial class Server_Form : Form { // Responsible for listening to the socket of the client Socket socket_TCP = null; // Socket responsible for communicating with client Socket socket_Communication = null; //Listen Thread Thread thread_Listen = null; //Client port number collection Dictionary<string, Socket> dic = new Dictionary<string, Socket>(); public Server_Form() { InitializeComponent(); Control.CheckForIllegalCrossThreadCalls = false; } private void button_Connection_Click(object sender, EventArgs e) { if (button_Connection.Text == "connect") { button_Connection.Text = "to break off"; socket_TCP = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse(textBox_IP.Text), (int)numericUpDown_Port.Value); socket_TCP.Bind(iPEndPoint); socket_TCP.Listen(0); thread_Listen = new Thread(TCP_Listen); thread_Listen.IsBackground = true; thread_Listen.Start(); } else if (button_Connection.Text == "to break off") { button_Connection.Text = "connect"; if (socket_Communication != null) { socket_Communication.Close(); } } } private void TCP_Listen() { while (true) { try { socket_Communication = socket_TCP.Accept(); //Client network node string RemoteEndPoint = socket_Communication.RemoteEndPoint.ToString(); dic.Add(RemoteEndPoint, socket_Communication); listBoxOnlineList.Items.Add(RemoteEndPoint); //Thread passing parameters ParameterizedThreadStart pts = new ParameterizedThreadStart(TCP_Read); Thread thread = new Thread(pts); thread.IsBackground = true; thread.Start(socket_Communication); } catch (Exception e) { break; } } } private void button_Send_Click(object sender, EventArgs e) { if (listBoxOnlineList.SelectedIndex == -1) { MessageBox.Show("Please select the client to send!", "Tips", MessageBoxButtons.OK, MessageBoxIcon.Stop); } else { string selectClient = listBoxOnlineList.Text; TCP_Write(textBox_Send.Text, selectClient); textBox_Send.Text = ""; } } private void TCP_Write(string data, string EndPoint) { try { dic[EndPoint].Send(Encoding.UTF8.GetBytes(data)); } catch (Exception e) { MessageBox.Show(e.Message); return; } } private void TCP_Read(object socket_Read) { Socket socket = socket_Read as Socket; while (true) { try { byte[] buffer_Data = new byte[1024 * 1024]; int Accept_length = socket.Receive(buffer_Data); EndPoint endPoint = socket.RemoteEndPoint; string Str_Data = Encoding.UTF8.GetString(buffer_Data, 0, buffer_Data.Length).Trim("\0".ToCharArray()); if (Str_Data.Substring(0,2) == "aa" && Str_Data.Substring(Str_Data.Length - 2, 2) == "AA") { switch (Str_Data.Substring(2,2)) { case "00": string str = null; foreach (var item in dic) { str += item.Key + " "; } TCP_Write(str, endPoint.ToString()); break; case "01": TCP_Write(Str_Data.Substring(19, Str_Data.Length - 21), Str_Data.Substring(4, 15)); break; default: break; } } else { richTextBox_Receive.AppendText("client " + endPoint + ":" + Str_Data + "\r\n"); } } catch (Exception) { //Prompt socket listening exception richTextBox_Receive.AppendText("client" + socket.RemoteEndPoint + "The connection has been disconnected" + "\r\n"); //Remove disconnected clients dic.Remove(socket.RemoteEndPoint.ToString()); //Remove disconnected clients from listbox listBoxOnlineList.Items.Remove(socket.RemoteEndPoint.ToString()); //Close the socket used to communicate with the client before accept ing socket_Communication.Close(); break; } } } } }
Client end program
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace Winform_Chat { public partial class Main_Form : Form { public Main_Form() { InitializeComponent(); Control.CheckForIllegalCrossThreadCalls = false; } // Create a TCP client socket Socket Socket_TCP = null; // Create a receive Thread thread_TCP_Read = null; private void button_Connection_Click(object sender, EventArgs e) { if (button_Connection.Text == "connect") { // Define a socket for listening to messages sent by clients, including three parameters (ipv4 addressing protocol, streaming connection, tcp protocol) Socket_TCP = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse(textBox_IP.Text), (int)numericUpDown_Port.Value); try { Socket_TCP.Connect(iPEndPoint); } catch (Exception a) { richTextBox_Receive.AppendText(a.Message + "\r\n"); return; } timer_Heartbeat.Start(); button_Connection.Text = "close"; thread_TCP_Read = new Thread(TCP_Read); thread_TCP_Read.IsBackground = true; thread_TCP_Read.Start(); } else if (button_Connection.Text == "close") { button_Connection.Text = "connect"; timer_Heartbeat.Stop(); Socket_TCP.Close(); } } private void button_Send_Click(object sender, EventArgs e) { string str_data = "aa01" + label3.Text + textBox_Send.Text.Trim() + "AA"; Socket_TCP.Send(Encoding.UTF8.GetBytes(str_data)); richTextBox_Receive.AppendText("Local machine:" + textBox_Send.Text.Trim() + "\r\n"); textBox_Send.Clear(); } private void TCP_Read() { while (true) { try { byte[] buffer_Data = new byte[1024 * 1024]; int Accept_length = Socket_TCP.Receive(buffer_Data); if (Accept_length > 0) { string Str_Data = Encoding.UTF8.GetString(buffer_Data, 0, buffer_Data.Length).Trim("\0".ToCharArray()); if (Str_Data.IndexOf(":") > 0) { listBox_Friends.Items.Clear(); string[] strData = Str_Data.Split(' '); for (int i = 0; i < strData.Length - 1; i++) { listBox_Friends.Items.Add(strData[i]); } } else { richTextBox_Receive.AppendText("The server:" + label3.Text + Str_Data + "\r\n"); } } } catch (Exception e) { richTextBox_Receive.AppendText(e.Message + "\r\n"); return; } } } private void timer_Heartbeat_Tick(object sender, EventArgs e) { try { string str_IP = "aa00aaAA"; Socket_TCP.Send(Encoding.UTF8.GetBytes(str_IP)); } catch (Exception) { richTextBox_Receive.AppendText("The server is down\r\n"); button_Connection.Text = "connect"; timer_Heartbeat.Stop(); Socket_TCP.Close(); } } private void listBox_Friends_SelectedIndexChanged(object sender, EventArgs e) { label3.Text = listBox_Friends.SelectedItem.ToString(); } } }
Effect display
summary
Link: https://pan.baidu.com/s/1XJ6ilnd9f_syx6NZfQiJZQ
Extraction code: m4rd