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

C# 撰寫簡易聊天程式(五):訊息收發者具體實作與非同步監聽

     編輯:關於C語言

MessageSender 實作

public class MessageSender : IMessageSender
{
    TcpClient client;
    Stream streamToServer;

    public bool Connect(IPAddress ip, int port)
    {
        try { client = new TcpClient(); client.Connect(ip, port); streamToServer = client.GetStream(); return true; }
        catch { return false; }
    }
    public bool SendMessage(Message msg)
    {
        try { lock (streamToServer) { byte[] buf = Encoding.Unicode.GetBytes(msg.ToString()); streamToServer.Write(buf, 0, buf.Length); return true; } }
        catch { return false; }
    }
    public void SignOut()
    {
        streamToServer?.Dispose();
        client?.Close();
    }
}

MessageReceiver 實作

public delegate void PortNumberReadyEventHandler(int port);

public class MessageReceiver : IMessageReceiver
{
    public event MessageReceivedEventHandler MessageReceived;
    public event ConnectionLostEventHandler ClientLost;
    public event ClientConnectedEventHandler ClientConnected;
    public event PortNumberReadyEventHandler PortNumberReady;

    Thread workerThread;
    TcpListener listener;

    public MessageReceiver() { ((IMessageReceiver)this).StartListen(); }

    void IMessageReceiver.StartListen()
    {
        workerThread = new Thread(ListenThreadMethod) { IsBackground = true };
        workerThread.Start();
    }

    private void ListenThreadMethod()
    {
        listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 0);
        listener.Start();
        int port = ((IPEndPoint)listener.LocalEndpoint).Port;
        PortNumberReady?.Invoke(port);

        while (true)
        {
            TcpClient remote;
            try { remote = listener.AcceptTcpClient(); }
            catch { break; }

            IPEndPoint ep = (IPEndPoint)remote.Client.RemoteEndPoint;
            ClientConnected?.Invoke(ep);

            Stream stream = remote.GetStream();
            byte[] buf = new byte[8192];
            while (true)
            {
                try
                {
                    int read = stream.Read(buf, 0, buf.Length);
                    if (read == 0) throw new Exception("Client disconnected");
                    string msg = Encoding.Unicode.GetString(buf, 0, read);
                    MessageReceived?.Invoke(msg);
                }
                catch (Exception ex)
                {
                    ClientLost?.Invoke(ex.Message);
                    break;
                }
            }
        }
    }

    public void StopListen()
    {
        try { listener.Stop(); listener = null; workerThread.Abort(); } catch { }
    }
}

使用雙層 while 迴圈處理多用戶連線,但同步阻塞模式下一次僅能服務一個用戶。四大事件供 UI 訂閱。

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