SOCKET Network Programming

Keywords: socket encoding less Windows

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:

  1. Create a SOCKET that monitors IP addresses and port numbers:
    Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  2. Get the local IP address: IPAddress ip = IPAddress.Any;
  3. Objects that create client-side links to IP and port addresses: IPEndPoint = new IPEndPoint (ip, Convert. ToInt32 (textBox_Port. Text));
  4. SOCKET listening client: socketWatch.Bind(point);
  5. 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();
  6. 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);
  7. Send a message to the client: dic[ip] (SOCKET linking the client). Send (new Buffer);
  8. Store multiple COKETs of linking clients in key-value pairs.
  9. 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:

  1. After running the server, you can open multiple clients by right-clicking the customer service project, [debugging-launching a new instance]
  2. CMD console input ipconfig, you can query the local IP address
  3. Create SOCKET for communication: socketSend = new Socket (AddressFamily. Internet, SocketType. Stream, ProtocolType. Tcp);
  4. Convert the string ip address to an instance of ip address: IPAddress ip = IPAddress.Parse(textBox_IP.Text);
  5. Objects to create server IP and port address: IPEndPoint = new IPEndPoint (ip, Convert. ToInt32 (textBox_Port. Text));
  6. Connect server: socketSend.Connect(point);
  7. 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);
  8. Open the Save File Dialog in the current form: sfd.ShowDialog(this);
  9. Get the coordinates of the current form: int X = this.Location.X; int Y = this.Location.Y;
  10. Reassign the new coordinates of the current form: this.Location = new Point(this.Location.X - 10, this.Location.Y - 10);
  11. 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);
            }
        }
    }
}

Posted by zizzy80 on Wed, 14 Aug 2019 04:24:51 -0700