整理之前的資料, 希望做到下列功能

1. 伺服端開啟一個執行緒, 隨時提供客戶端連線

2. 伺服端當偵測到客戶連線, 則啟動另一個執行緒監聽客戶端傳來的內容

3. 伺服端可以隨時暫停/繼續服務, 在此同時也不能讓伺服端和客戶端程式當機

4. 當伺服端暫停服務時, 客戶端會顯示”等待伺服端啟動服務…”

5. 當伺服端再繼續服務時, 客戶端可以自動偵測並自動連線, 傳送資料

6. 客戶端開啟一個執行緒, 並可隨時暫停/繼續傳送資料, 在此同時也不能讓伺服端和客戶端程式當機

7. 當客戶端停止連線, 伺服端會顯示”等待客戶端連線…”

image

加入新項目 TCPServerAP.cs

image

using System.Net;             // 匯入通訊協定 
using System.Net.Sockets;     // 匯入網路插座功能函數 
using System.Threading;       // 匯入多執行緒功能函數
using System.Collections;     // 匯入集合物件功能

1. 設計一個Thread class

namespace TCPServerApp
{
    public class TCPServerAP
    {
        ManualResetEvent m_shutdownEvent = new ManualResetEvent(false);
        ManualResetEvent m_pauseEvent = new ManualResetEvent(true);
        Thread m_thread;
        int m_cnt = 0;
        public TCPServerAP() { }
        private void Job()
        {
            while (true)
            {
                m_pauseEvent.WaitOne(Timeout.Infinite);
                if (m_shutdownEvent.WaitOne(0)) 
                    break;
                m_cnt++;
            }
        }
        public void Start()
        {
            m_thread = new Thread(Job);
            m_thread.IsBackground = true;
            m_thread.Start();
        }
        public void Pause()
        {
            m_pauseEvent.Reset();
        }
        public void Resume()
        {
            m_pauseEvent.Set();
        }
        public void Stop()
        {
            m_pauseEvent.Set();
            m_shutdownEvent.Set();
            m_thread.Join();
        }
    }
}

2. 執行緒中如何更新UI?

2.1 加入Label設定/取值功能

public Label CntLabel
{
    set;
    get;
}

2.2 加入更新UpdateUI

private void UpdateUI()
{
    if (CntLabel.InvokeRequired)
    {
        CntLabel.BeginInvoke((Action)(() => { UpdateUI(); }));
    }
    else
    {
        CntLabel.Text = m_cnt.ToString();
    }
}

2.3 UI加入對應事件

private void 開始ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tcp1 = new TCPServerAP();
            tcp1.CntLabel = label1;
            tcp1.Start();
        }
 
        private void 暫停ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tcp1.Pause();
        }
 
        private void 繼續ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tcp1.Resume();
        }
 
        private void 停止ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tcp1.Stop();
        }

2.4 修改Job

private void Job()
{
    while (true)
    {
        m_pauseEvent.WaitOne(Timeout.Infinite);
        if (m_shutdownEvent.WaitOne(0)) 
            break;
        m_cnt++;
        UpdateUI();
        Thread.Sleep(1);     // 不能省略, 否則UI來不及更新
    }
}

測試Thread class

image

=========================================================================

TCPServerAP加入IP和Port

public string IP
{
    get;
    set;
}
public int Port
{
    get;
    set;
}

UI加入取得IP和Port

TCPServerAP加入下列資料成員

public class TCPServerAP
   {
       ManualResetEvent m_shutdownEvent = new ManualResetEvent(false);  
       ManualResetEvent m_pauseEvent = new ManualResetEvent(true);
       
       TcpListener m_server;                           // 伺服端網路監聽
       Socket m_client;                                // 客戶連線物件   
       Thread m_threadServer;                          // 伺服器監聽用執行緒 
       Thread m_threadClient;                          // 客戶用的通話執行緒
       Hashtable m_table = new Hashtable();
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 me1237guy 的頭像
    me1237guy

    天天向上

    me1237guy 發表在 痞客邦 留言(2) 人氣()