首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 2.0 Socket 程式設計範例初探(四):WinForms Client/Server 聊天室、非同步接收、UTF8/GB2312 編碼轉換、FTP 擴充展望

     編輯:關於C語言

Client 端完整程式碼


// Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.IO;
using System.Threading;

namespace ClientTest
{
    public partial class Form1 : Form
    {
        Socket client;
        public string host = "";
        int port = 2000;
        Thread Data;
        public string nick = "";
        Encoding utf8 = Encoding.UTF8;
        Encoding gb2312 = Encoding.GetEncoding("GB2312");
        delegate void SetSafe(string text);

        public Form1() { InitializeComponent(); }

        private void button1_Click(object sender, EventArgs e) // 連線
        {
            Form2 frm2 = new Form2();
            frm2.ShowDialog();
            host = frm2.textBox2.Text;
            nick = frm2.textBox1.Text;
            try
            {
                client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                client.Connect(host, port);
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

        private void Form1_Load(object sender, EventArgs e) // 啟動接收執行緒
        {
            Data = new Thread(new ThreadStart(DataStart));
            Data.Start();
        }

        public void DataStart() // 持續接收伺服器訊息
        {
            while (true)
            {
                try
                {
                    NetworkStream ns = new NetworkStream(client);
                    StreamReader reader = new StreamReader(ns);
                    string result = reader.ReadLine();
                    byte[] u = utf8.GetBytes(result);
                    byte[] gb = Encoding.Convert(utf8, gb2312, u);
                    string sGb = gb2312.GetString(gb);
                    AddList(sGb);
                    reader.Close(); ns.Close();
                }
                catch { }
                Thread.Sleep(1000);
            }
        }

        private void button3_Click(object sender, EventArgs e) // 發言
        {
            try
            {
                string sendString = "(" + client.LocalEndPoint + ")" + nick + "說" + textBox1.Text + "\r\n";
                byte[] butf = utf8.GetBytes(sendString);
                client.Send(butf);
            }
            catch { }
        }

        private void AddList(object text) // 跨執行緒更新 UI
        {
            if (this.listBox1.InvokeRequired)
            {
                SetSafe d = new SetSafe(AddList);
                this.Invoke(d, new object[] { text });
            }
            else this.listBox1.Items.Add(text);
        }

        private void Closing(object sender, FormClosingEventArgs e) // 關閉通知 Server
        {
            try
            {
                Data.Abort();
                Byte[] buf = Encoding.UTF8.GetBytes("Close\r\n");
                client.Send(buf);
            }
            catch { }
        }
    }
}

Server 端完整程式碼


// Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Net.Sockets;
using System.Collections;

namespace ServerTest
{
    public partial class Form1 : Form
    {
        int port = 2000;
        TcpListener listener;
        delegate void SetSafe(string text);
        ArrayList conList = new ArrayList();
        Encoding utf8 = Encoding.UTF8;
        Encoding gb2312 = Encoding.GetEncoding("GB2312");
        Thread listenerThread, DataThread;

        public Form1() { InitializeComponent(); }

        public void AcceptRequest() // 連線處理執行緒
        {
            while (true)
            {
                try
                {
                    if (listener.Pending())
                    {
                        Socket s = listener.AcceptSocket();
                        conList.Add(s);
                        if (s.Connected)
                        {
                            string msg = "歡迎登陸伺服器" + s.LocalEndPoint + "\r\n";
                            byte[] bgb = gb2312.GetBytes(msg);
                            byte[] butf = Encoding.Convert(gb2312, utf8, bgb);
                            s.Send(butf);
                            AddList(s.RemoteEndPoint.ToString());
                        }
                    }
                }
                catch { }
                Thread.Sleep(1000);
            }
        }

        public void ReceiveData() // 資料處理執行緒
        {
            while (true)
            {
                try
                {
                    ArrayList closeList = new ArrayList();
                    foreach (Socket s in conList)
                    {
                        NetworkStream ns = new NetworkStream(s);
                        StreamReader reader = new StreamReader(ns);
                        if (ns.DataAvailable)
                        {
                            string result = reader.ReadLine();
                            byte[] u = utf8.GetBytes(result);
                            byte[] gb = Encoding.Convert(utf8, gb2312, u);
                            string sGb = gb2312.GetString(gb);
                            if (sGb.StartsWith("Close")) closeList.Add(s);
                            else
                            {
                                foreach (Socket p in conList) // 廣播給所有客戶端
                                {
                                    byte[] butf = utf8.GetBytes(result + "\r\n");
                                    p.Send(butf);
                                }
                            }
                        }
                        reader.Close(); ns.Close();
                    }
                    foreach (Socket s in closeList)
                    {
                        DelList(s.RemoteEndPoint.ToString());
                        s.Close(); conList.Remove(s);
                    }
                }
                catch { }
                Thread.Sleep(1000);
            }
        }

        private void button1_Click(object sender, EventArgs e) // 啟動伺服器
        {
            listener = new TcpListener(port);
            listener.Start();
            listenerThread = new Thread(new ThreadStart(AcceptRequest));
            listenerThread.Start();
            DataThread = new Thread(new ThreadStart(ReceiveData));
            DataThread.Start();
        }

        private void AddList(object text) { /* 同 Client Invoke 模式 */ }
        private void DelList(object text) { /* 同 Client Invoke 模式 */ }

        private void button2_Click(object sender, EventArgs e) // 踢人
        {
            string temp = listBox1.SelectedItem.ToString();
            DelList(temp);
            foreach (Socket f in conList)
                if (f.RemoteEndPoint.ToString() == temp)
                {
                    byte[] butf = Encoding.Convert(gb2312, utf8,
                        gb2312.GetBytes("你被伺服器踢了\r\n"));
                    f.Send(butf);
                    conList.Remove(f); f.Close();
                }
        }

        private void Closing(object sender, FormClosingEventArgs e)
        {
            foreach (Socket o in conList) o.Close();
            listenerThread.Abort(); DataThread.Abort();
        }
    }
}

擴充方向:FTP / 遊戲協定

實務中伺服器需處理多種指令(移動、攻擊、上傳/下載檔案),採用「指令+內容+結束符」格式,接收端解析分派。下一篇將示範 FTP 檔案清單、上傳下載、斷線管理完整範例。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved