Socket編程(一):建立與客戶端的連接並接受數據


我們這里利用Socket在模擬一個客戶端與服務器通信,其實客戶端與服務端通信就像人與人打電話一樣,想要給一個人打電話,我們首先必須要有手機,必須知道對方的手機號碼,這里Socket就好比一部手機,而短點就好比手機號,但是當你撥了電話,還需要對方接了以后才算是可以通信,下面我們來看一看代碼:

首先寫服務器端:

 

這里我們指定一個ip地址和端口號:然后開始對它進行監聽;

        private void btnListen_Click(object sender, EventArgs e)
        {
            //ip地址
            IPAddress ip = IPAddress.Parse(this.txtServer.Text);
            //網絡端口號
            IPEndPoint endpoint = new IPEndPoint(ip, int.Parse(txtPort.Text));

            //負責監聽的Socket
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //綁定本地短點
            try
            {
                socket.Bind(endpoint);//這里綁定一個端點
                socket.Listen(10);
                SetText("開始監聽");
                btnListen.Enabled = false;
            }
            catch(Exception ex)
            {
                btnListen.Enabled = true;
                SetText(ex.Message);
                return;
            }

            //創建線程,用來執行socket監聽客戶端,為什么要創建一個線程呢,因為這里我想多找一個人來干活,讓它替主線程分擔點任務
            Thread th = new Thread(Accept);
            th.IsBackground = true;//設置為后台線程
            th.Start(socket);
        }

        Dictionary<string, Socket> dic = new Dictionary<string, Socket>();

        int n = 10;//創建10個客戶端的連接
        //接受客戶端的連接,避免主線程陷入死循環
        void Accept(object o)
        {
            while (n>0)
            {
                n--;
                //監聽用的Socket
                Socket socket = o as Socket;

                //當有客戶端連接成功后,創建通信用的Socket
                Socket connSocket = socket.Accept();

                //獲取客戶端ip和端口號
                string ip = connSocket.RemoteEndPoint.ToString();
                //把客用戶端ip和通信用的Socket存放到字典中
                dic.Add(ip, connSocket);
                cmbIP.Items.Add(ip);

                //提示連接成功
                SetText( ip+ "連接成功!");
                //服務端接受客戶端發來的信息
                Thread th = new Thread(ReciveMsg);
                th.Start(connSocket);
            }

            
        }

那么如果客戶端接了電話,那么我們要接收客戶端的發來的信息

 1   void ReciveMsg(object o)
 2         {
 3             Socket connSocket = o as Socket;//我們這個Socket是我們上面創建的用來連接通信的,與監聽的Scoket區別開
 4             byte[] buffer = new byte[1024 * 1024 * 5];//設置最多接收5兆的信息
 5             while (true)//這里我們循環接收客戶端的信息,客戶端可以一直發信息,我們創建線程的好處就在這里,因為主線程一旦陷入死循環,那么這個程序就卡了
 6             {
 7                 int count = connSocket.Receive(buffer);//把接收到的信息放在buffer中
 8                 if (count > 0)
 9                 {
10                     string s = Encoding.UTF8.GetString(buffer, 0, count);
11                     SetText(connSocket.RemoteEndPoint.ToString() + ":" + s);
12                 }
13                 else
14                 {
15                     SetText(connSocket.RemoteEndPoint.ToString()+"斷開連接");
16                     connSocket.Close();
17                     break;
18                 }
19             }
20         }

 

 /// <summary>
        /// 發送消息 開頭標記為0
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            //判斷下拉框是否有選項
            if (cmbIP.SelectedIndex >= 0)
            {
                string key = cmbIP.Text;
                byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text);
                List<byte> list = new List<byte>();
                list.Add(0);
                list.AddRange(buffer);
                dic[key].Send(list.ToArray());
            }
            else
            {
                MessageBox.Show("請選擇客戶端用戶!");
            }
        }

 

 1 /// <summary>
 2         /// 發送文件
 3         /// </summary>
 4         /// <param name="sender"></param>
 5         /// <param name="e"></param>
 6         private void button2_Click(object sender, EventArgs e)
 7         {
 8             if (!string.IsNullOrEmpty(txtFilePath.Text))
 9             {
10                 if (cmbIP.SelectedIndex >= 0)
11                 {
12                     string key = cmbIP.Text;
13                     FileStream fs = new FileStream(txtFilePath.Text, FileMode.Open);
14                     byte[] buffer=new  byte[fs.Length];
15                     fs.Read(buffer, 0, buffer.Length);
16                      
17                     //文件 標記開頭為1
18                     List<byte> list = new List<byte>();
19                     list.Add(1);
20                     list.AddRange(buffer);
21 
22                     dic[key].Send(list.ToArray());
23                 }
24                 else
25                 {
26                     MessageBox.Show("請選擇客戶端用戶!");
27                 }
28             }
29             else
30             {
31                 MessageBox.Show("請選擇文件!");
32             }
33         }


先把服務器端的寫一下。

 


免責聲明!

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



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