客戶端筆記

開心市民小顧發表於2021-01-03

初級版本實現傳送文字資訊

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 _11.聊天程式客戶端
{
    public partial class Form1 : Form
    {
        public Socket ClientScoket { get; set; }
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //建立Socket物件
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            ClientScoket = socket;
            //連線伺服器端
            try
            {
                socket.Connect(IPAddress.Parse(textBox1.Text), int.Parse(textBox2.Text));

            }
            catch (Exception)
            {
                //應該是sleep睡一會然後在連線
                textBox3.Text = $"伺服器連線錯誤"+textBox3.Text;
                return;
            }
            //傳送訊息
            Thread thread = new Thread(new ParameterizedThreadStart(ReceiveDate));
            thread.IsBackground = true;
            thread.Start(ClientScoket);
            //接收訊息

        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (ClientScoket.Connected)
            {
                byte[] bytes = Encoding.Default.GetBytes(textBox4.Text.Trim());
                ClientScoket.Send(bytes, 0, bytes.Length, SocketFlags.None);
            }
        }
        private void ReceiveDate(object state)
        {
            //接受客戶端來的訊息
            byte[] data = new byte[1024 * 1024];
          
                //方法的返回值表示實際上接收的資料長度(位元組數)
                try
                {
                    int realLen = ((Socket)state).Receive(data, 0, data.Length, SocketFlags.None);
                    //表示對方退出了
                    if (realLen == 0)
                    {
                        this.textBox3.Invoke(new Action(() => {
                            textBox3.Text = $"伺服器端{ ((Socket)state).RemoteEndPoint.ToString()}退出了\r\n{ textBox1.Text}";
                        }));

                        ((Socket)state).Shutdown(SocketShutdown.Both);
                        ((Socket)state).Close();
                    
                        return;
                    }
                    string x = Encoding.Default.GetString(data, 0, realLen);
                    this.textBox3.Invoke(new Action(() => {
                        textBox3.Text = $"接收伺服器傳送來的訊息{ ((Socket)state).RemoteEndPoint.ToString()}{x}\r\n{ textBox1.Text}";
                    }));
                }
                catch
                {
                    this.textBox3.Invoke(new Action(() => {
                        textBox3.Text = $"伺服器端{ ((Socket)state).RemoteEndPoint.ToString()}異常退出了\r\n{ textBox1.Text}";
                    }));
                    ((Socket)state).Shutdown(SocketShutdown.Both);
                    ((Socket)state).Close();
                
                    return;
                }
            

        }
    }
}

實現視窗抖動和檔案傳送

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.OleDb;
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 socket聊天客戶端
{
    public partial class Form1 : Form
    {
        public Socket ClientSocket { get; set; }
        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //客戶端連線伺服器
            //1.建立Socket物件
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            ClientSocket = socket;
            //2.連線伺服器端
            try
            {
                socket.Connect(new IPEndPoint(IPAddress.Parse(textBox1.Text), int.Parse(textBox2.Text)));
            }
            catch (Exception ex)
            {
                Thread.Sleep(500);
                MessageBox.Show(ex.Message);
                button1_Click(this, e);
                return;
            }
            //3.收發訊息
            //Thread thread = new Thread(new ParameterizedThreadStart(ReceiveClient));
            //thread.IsBackground = true;
            //thread.Start(ClientSocket);
            ThreadPool.QueueUserWorkItem(new WaitCallback(ReceiveClient), ClientSocket);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (ClientSocket.Connected)
            {
                byte[] data = Encoding.Default.GetBytes(textBox3.Text);
                ClientSocket.Send(data, 0, data.Length, SocketFlags.None);
            }
        }
        private void ReceiveClient(object socket)
        {

            byte[] data = new byte[1024 * 1024];
            while (true)
            {
                int callLen = 0;
                try
                {
                    callLen = ((Socket)socket).Receive(data, 0, data.Length - 1, SocketFlags.None);
                }
                catch (Exception ex)
                {
                    //異常退出

                    MessageBox.Show(ex.Message);
                    StopContent();
                    return;
                }
                if (callLen <= 0)
                {
                    //伺服器端正常退出
                    this.AppendTextToTxtLog(string.Format("伺服器端:{0}正常退出", ((Socket)socket).RemoteEndPoint.ToString()));
                    StopContent();//停止連線
                    return;//讓方法結束,終結當前接受客戶端資料的非同步執行緒
                }
                //接收資料中的第一個位元組判斷
                #region 接收的字串
                if (data[0] == 1)
                {
                    ProcessrecieveMethod(socket, data, callLen);
                }else if (data[0] == 2)
                {
                    Point oldLoction = this.Location;
                    Random r = new Random();
                    for(int i = 0; i < 50; i++)
                    {
                        this.Location = new Point(r.Next(oldLoction.X-100, oldLoction.X + 100),r.Next(oldLoction.Y - 100, oldLoction.Y+100));
                        Thread.Sleep(20);
                        this.Location = oldLoction;
                    }
                }
                else if(data[0]==3)
                {
                    using (SaveFileDialog sfd = new SaveFileDialog()) 
                    {
                        sfd.DefaultExt = "txt";
                        sfd.Filter = "文字檔案(*.txt)|*.txt|所有檔案(*.*)|*.*";
                        if (sfd.ShowDialog(this) != DialogResult.OK)
                        {
                            return;
                        }
                        byte[] fileDate = new byte[callLen - 1];
                        Buffer.BlockCopy(data, 1, fileDate, 0, callLen - 1);
                   
                        File.WriteAllBytes(sfd.FileName,fileDate);
                     }      
                }
                #endregion 
            }
        }

        private void ProcessrecieveMethod(object socket, byte[] data, int callLen)
        {
            string ReceiveMsg = Encoding.Default.GetString(data, 1, callLen-1);
            this.AppendTextToTxtLog(string.Format("接收到伺服器端:{0}的訊息是{1}", ((Socket)socket).RemoteEndPoint.ToString(), ReceiveMsg));
        }

        private void StopContent()
        {
            try
            {

                if (ClientSocket.Connected)
                {
                    ClientSocket.Shutdown(SocketShutdown.Both);
                    ClientSocket.Close();
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        private void AppendTextToTxtLog(string ReceiveMsg)
        {
            if (richTextBox1.InvokeRequired)
            {
                richTextBox1.Invoke(new Action<string>(s => {
                    this.richTextBox1.Text = string.Format("{0}\r\n{1}", s, richTextBox1.Text);
                }), ReceiveMsg);
            }
            else
            {
                this.richTextBox1.Text = string.Format("{0}\r\n{1}", ReceiveMsg, richTextBox1.Text);
            }

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //判斷是否已連線,如果連結那麼就關閉連線
            StopContent();
        }
    }
}

相關文章