多線程和Socket網絡編程(一)


視頻:https://www.bilibili.com/video/BV1FJ411v7hv?p=15

進程:每一個應用程序都當做一個進程。

using System;
    using System.Diagnostics;
    
    namespace ConsoleApp2
    {
        class Program
        {
            static void Main(string[] args)
            {
                foreach (var item in Process.GetProcesses())
                {
                    //關閉進程,可能先要獲取權限
                    item.Kill();
                    Console.WriteLine(item);
                }
    
                // 打開程序
                Process.Start("calc");
                Process.Start("iexplore");
    
                // 打開詳細的文件
                ProcessStartInfo startInfo = new ProcessStartInfo(@"C:\Users\bibi\Desktop\工作.xlsx");
                Process process = new Process();
                process.StartInfo = startInfo;
                process.Start();
            }
        }    
    }
View Code

線程:其他子線程的創建可以有效避免UI主線程的卡死,線程分前台線程和后台線程,當所有前台線程已經關閉,后台線程自動關閉。跨線程訪問UI主線程要注意UI主線程的銷毀可能帶來的異常。銷毀掉的線程無法重啟。

using System;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace WindowsFormsApp2
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            Thread thread;
    
            private void button1_Click(object sender, EventArgs e)
            {
                // 創建一個子線程,傳入方法。
                thread = new Thread(() =>
                {
                    for (int i = 0; i < 10000; i++)
                    {
                        Console.WriteLine(i);
                    }
                });
                // 1、設置線程為后台線程 2、標記線程就緒,何時執行由CPU決定。
                thread.IsBackground = true;
                thread.Start();
            }
    
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (thread != null)
                {
                    thread.Abort();
                }
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                // 取消跨線程調用的檢查
                Control.CheckForIllegalCrossThreadCalls = false;
            }
        }
    }
View Code

線程方法傳參:方法的參數類型必須為Object。

 

Socket:程序與程序直接的一種通信機制,也稱“套字節”。通過Socket需要知道程序對應的ip地址和端口。Socket涉及協議TCP或UDP,TCP三次握手、安全穩定、效率低,UDP容易發生數據丟失、效率高。

服務端使用Socket步驟:1、Bind函數綁定監聽端點,2、Listen函數設置監聽隊列(在某個時間內允許的最多連接數)3、Accept函數等待接收客戶端的連接

4、放進后台線程等待客戶端的連接,每有一個新的連接,就創建一個新的Socket,使用“While(true){...等待客戶端的連接...}”,5、使用Receive函數接收客戶端發過來的消息,如果客戶端下線了,接收到的消息為空即0字節。

 private void button1_Click(object sender, EventArgs e)
 {
     Socket socket = new Socket(SocketType.Stream,ProtocolType.Tcp);
     IPAddress ip = IPAddress.Any;
     IPEndPoint endPoint = new IPEndPoint(ip, 8083);
     socket.Bind(endPoint);
     MessageBox.Show("監聽成功");
     socket.Listen(10);
     // 等待客戶端的連接
     Socket socketSend = socket.Accept();
     MessageBox.Show(socketSend.RemoteEndPoint.ToString()+"連接成功");

     // 客戶端連接成功后,服務器可以收到客戶端發送過來的消息。
     byte[] buffer = new byte[1024 * 1024 * 2];
     int r = socketSend.Receive(buffer);
     // 獲取客戶端發過來的字符串
     string str = Encoding.UTF8.GetString(buffer, 0, r);
 }
View Code

客戶端使用Socket步驟:1、Connect函數連接服務端,2、Send函數發送消息(服務端發送消息給客戶端,也是使用客戶端的Socket來Send字節),3、Receive函數接收服務端發送過來的消息

Socket socket = new Socket(SocketType.Stream,ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse("192.169.11.87");
IPEndPoint endPoint = new IPEndPoint(ip, 5000);
socket.Connect(endPoint);

string msg = "消息來了";
byte[] buffer = Encoding.UTF8.GetBytes(msg);
socket.Send(buffer);
View Code

Socket和多線程一起運用的聊天舉例:

在服務端中,服務端開啟一個后台線程不停的新的客戶端連接,每個客戶端連接Socket都單獨開啟一個后台線程來接收客戶端發送過來的消息。

在客戶端中,開啟一個后台線程來接收服務器發送過來的消息。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM