SOCKET
Scoket: Program-to-program communication is like people using [telephones] to communicate, and programs using [SCOKET] to communicate.
SOCKET, commonly known as socket, is used to describe [IP address] and [port], and is the handle of a communication chain.
IP Address: Used to locate computers in the network
Port number: Used to locate programs on a computer
Protocol: The language between computers needs a unified way of language, so that computers can communicate effectively.
UDP Protocol: High Efficiency, Instability and Easy Data Loss
TCP protocol: secure, stable, but inefficient
Create Scoket Server
Knowledge Points:
- Create a SOCKET that monitors IP addresses and port numbers:
Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - Get the local IP address: IPAddress ip = IPAddress.Any;
- Objects that create client-side links to IP and port addresses: IPEndPoint = new IPEndPoint (ip, Convert. ToInt32 (textBox_Port. Text));
- SOCKET listening client: socketWatch.Bind(point);
- Waiting for a client's connection and creating a SOCKET to communicate with it (the waiting state program will fake death, so arrange threads to execute):
socketSend = socketWatch.Accept(); - Receive the message sent by the client and return the number of valid bytes (receive the message with thread loop): int r = socketSend.Receive(buffer);
- Send a message to the client: dic[ip] (SOCKET linking the client). Send (new Buffer);
- Store multiple COKETs of linking clients in key-value pairs.
- The use of try {catch {} can reduce the abnormal errors and affect the user experience. (Of course, the debugging phase is less than try-catch)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; 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 _03_demo { public partial class Form1 : Form { Dictionary<string, Socket> dic = new Dictionary<string, Socket>(); public Form1() { InitializeComponent(); } /// <summary> /// Listening to Open Client Connection /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Button_Monitor_Click(object sender, EventArgs e) { //Create a SOCKET responsible for listening for IP addresses and port numbers Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress ip = IPAddress.Any; //Create Port Number Object IPEndPoint point = new IPEndPoint(ip,Convert.ToInt32(textBox_Port.Text)); //Monitor socketWatch.Bind(point); ShowMsg("Successful monitoring!"); //Number of simultaneous monitors socketWatch.Listen(10); //Create new threads to execute connections to listen on clients, and avoid socket s waiting for client connections, causing false death Thread th = new Thread(Listen); th.IsBackground = true; th.Start(socketWatch); } /// <summary> /// Wait for the customer to connect and create a SOCKET to communicate with /// </summary> /// Socket socketSend; void Listen(object o) { Socket socketWatch = o as Socket; //Waiting for Connection with Customers while (true) { //Wait for the customer to connect and create a SOCKET to communicate with socketSend = socketWatch.Accept(); //Add the client address to the key-value pair dic.Add(socketSend.RemoteEndPoint.ToString(),socketSend); //Add the client's address to the drop-down box comboBox_IP.Items.Add(socketSend.RemoteEndPoint.ToString()); ShowMsg(socketSend.RemoteEndPoint.ToString() + ": Connect successfully!"); //New thread execution receives messages from customers Thread th = new Thread(Receive); th.IsBackground = true; th.Start(socketSend); } } /// <summary> /// Receive messages from clients and output them to text boxes /// </summary> /// <param name="o"></param> void Receive(object o) { while (true) { try { Socket socketSend = o as Socket; //When the client connection is successful, the server should receive messages from the client byte[] buffer = new byte[1024 * 1024 * 2]; //The return value is the valid byte actually received int r = socketSend.Receive(buffer); //Determine whether the client stops running, and if the client stops running, exit the loop if (r == 0) { break; } //Converting byte data into strings string s = Encoding.UTF8.GetString(buffer, 0, r); ShowMsg(socketSend.RemoteEndPoint + ": " + s); } catch { } } } /// <summary> /// Print text in the log box /// </summary> /// <param name="str"></param> void ShowMsg(string str) { textBox_Log.AppendText(str +"\r\n"); } /// <summary> /// Turn off checking for cross-threaded operations /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_Load(object sender, EventArgs e) { Control.CheckForIllegalCrossThreadCalls = false; } /// <summary> /// Send Message Button /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Button4_Click(object sender, EventArgs e) { Thread th = new Thread(Send); th.IsBackground = true; th.Start(); } /// <summary> /// Get the content of the text box and send it to the client by character /// </summary> void Send() { string s = textBox_Input.Text.Trim(); byte[] buffer = Encoding.UTF8.GetBytes(s); List<byte> list = new List<byte>(); //The first byte is 0, indicating that the data transferred is text. list.Add(0); list.AddRange(buffer); byte[] newBuffer = list.ToArray(); string ip = comboBox_IP.SelectedItem.ToString(); dic[ip].Send(newBuffer); } /// <summary> /// Select the file and enter the file address into the text box /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Button2_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.InitialDirectory = @"C:\Users\shen\Desktop"; ofd.Filter = "All documents|*.*"; ofd.ShowDialog(); textBox_File.Text = ofd.FileName; } /// <summary> /// Send file to client /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Button3_Click(object sender, EventArgs e) { string path = textBox_File.Text; using(FileStream fsr = new FileStream(path, FileMode.Open, FileAccess.Read)) { byte[] buffer = new byte[1024 * 1024 * 5]; int r = fsr.Read(buffer, 0, buffer.Length); List<byte> list = new List<byte>(); //The first byte is 0, which means that the file is transferred. list.Add(1); list.AddRange(buffer); byte[] newBuffer = list.ToArray(); string ip = comboBox_IP.SelectedItem.ToString(); dic[ip].Send(newBuffer,0,r+1,SocketFlags.None); } } /// <summary> /// Send Vibration Button /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Button5_Click(object sender, EventArgs e) { byte[] buffer = new byte[1]; //The first byte is 0, which means that the vibration instruction is transmitted. buffer[0] = 2; string ip = comboBox_IP.SelectedItem.ToString(); dic[ip].Send(buffer); } } }
Create Socket Client
Knowledge Points:
- After running the server, you can open multiple clients by right-clicking the customer service project, [debugging-launching a new instance]
- CMD console input ipconfig, you can query the local IP address
- Create SOCKET for communication: socketSend = new Socket (AddressFamily. Internet, SocketType. Stream, ProtocolType. Tcp);
- Convert the string ip address to an instance of ip address: IPAddress ip = IPAddress.Parse(textBox_IP.Text);
- Objects to create server IP and port address: IPEndPoint = new IPEndPoint (ip, Convert. ToInt32 (textBox_Port. Text));
- Connect server: socketSend.Connect(point);
- Receive the message sent by the client and return the number of valid bytes (receive the message with thread loop): int r = socketSend.Receive(buffer);
- Open the Save File Dialog in the current form: sfd.ShowDialog(this);
- Get the coordinates of the current form: int X = this.Location.X; int Y = this.Location.Y;
- Reassign the new coordinates of the current form: this.Location = new Point(this.Location.X - 10, this.Location.Y - 10);
- The use of try {catch {} can reduce the abnormal errors and affect the user experience. (Of course, the debugging phase is less than try-catch)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; 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 _04_demo { public partial class Form1 : Form { Socket socketSend; public Form1() { InitializeComponent(); } /// <summary> /// Client sends message to server /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Button2_Click(object sender, EventArgs e) { //Gets the string of the input box string s = textBox_input.Text.Trim(); //Converting strings to byte arrays byte[] buffer = Encoding.UTF8.GetBytes(s); //Send a message to the server socketSend.Send(buffer); } /// <summary> /// Output text to the log box /// </summary> /// <param name="s"></param> void ShowMsg(string s) { textBox_Log.AppendText(s + "\n"); } /// <summary> /// Connecting servers /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Button_Link_Click(object sender, EventArgs e) { //Create SOCKET responsible for communication socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //Converting a string ip address to an ip address instance IPAddress ip = IPAddress.Parse(textBox_IP.Text); //Get IP address and port number IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(textBox_Port.Text)); //Connecting servers socketSend.Connect(point); ShowMsg("Connect successfully!"); //Create threads to execute receive server messages Thread th = new Thread(Receive); th.IsBackground = true; th.Start(); } /// <summary> /// Continuous Receiving of Server Messages /// </summary> void Receive() { while (true) { //Create byte arrays to receive server messages byte[] buffer = new byte[1024 * 1024 * 2]; //Receive the message from the server and return the number of valid bytes int r = socketSend.Receive(buffer); //Determine whether the server stops and if it stops, exit the loop if (r == 0) { break; } if (buffer[0] == 0) { //Converting byte arrays to strings string s = Encoding.UTF8.GetString(buffer, 1, r-1); ShowMsg(socketSend.RemoteEndPoint + ": " + s); } else if (buffer[0] == 1) { SaveFileDialog sfd = new SaveFileDialog(); sfd.InitialDirectory = @"C:\Users\shen\Desktop"; sfd.Filter = "All documents|*.*"; sfd.Title = "Save files"; sfd.ShowDialog(this); string path = sfd.FileName; using(FileStream fsw = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)) { fsw.Write(buffer, 1, r - 1); } MessageBox.Show("Save successfully!"); } else if (buffer[0] == 2) { Shake(); } } } /// <summary> /// Turn off checking for cross-threaded operations /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_Load(object sender, EventArgs e) { Control.CheckForIllegalCrossThreadCalls = false; } /// <summary> /// Vibration effect of form /// </summary> void Shake() { for(int i = 0; i < 500; i++) { this.Location = new Point(this.Location.X - 10, this.Location.Y - 10); this.Location = new Point(this.Location.X + 20, this.Location.Y + 20); this.Location = new Point(this.Location.X - 10, this.Location.Y - 10); } } } }