a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C# > 正文

基于UDP、TCP協(xié)議的C#網(wǎng)絡(luò)編程

2023-05-12 12:29:37
字體:
供稿:網(wǎng)友

與UDP不同,基于TCP協(xié)議的編程的服務(wù)器端有一個(gè)監(jiān)聽對(duì)象:TcpListener,它負(fù)責(zé)監(jiān)聽來自客戶端的消息并處理,并且必須在保持連接的情況下與客戶端保持互動(dòng),下面舉個(gè)例子來說明這個(gè)問題。

 示例一:基于TCP協(xié)議的網(wǎng)絡(luò)編程

窗體:

  Form2做為本程序的服務(wù)器端,當(dāng)按下Start后,啟動(dòng)服務(wù),剩下的是一個(gè)Form1,我啟動(dòng)了兩次,都連接到Form2,當(dāng)在Form1的Send欄里寫入小寫字母并按下Send按鈕后,將該字符串發(fā)送至Form2,同時(shí)Form2將該字符串轉(zhuǎn)換為大寫,返回給發(fā)送者,說明完畢,出個(gè)謎語,誰知道兩個(gè)Form1里字母是啥意思?

       Form2:(服務(wù)器端)

public partial class Form2 : Form
    {

        //聲明監(jiān)聽對(duì)象
        private TcpListener tl;

        //聲明網(wǎng)絡(luò)流
        private NetworkStream ns;
        public Form1()
        {
            CheckForIllegalCrossThreadCalls = false;
            InitializeComponent();           
        }

        private void btnStart_Click(object sender, EventArgs e)
        {

            //開啟8888端口的監(jiān)聽
            tl = new TcpListener(8888);
            tl.Start();

            //開啟線程
            Thread th = new Thread(new ThreadStart(listen));
            th.IsBackground = true;
            th.Start();
        }
        private void listen()
                 
            while (true)
             

                //獲得響應(yīng)的Socket
                Socket sock = tl.AcceptSocket();  

                //通過該Socket實(shí)例化網(wǎng)絡(luò)流           
                ns = new NetworkStream(sock);

                //ClientTcp是添加的類,下面會(huì)做說明
                ClientTcp ct = new ClientTcp(ns);

                //ct_MyEvent方法注冊(cè)ClientTcp類的MyEvent事件
                ct.MyEvent += new MyDelegate(ct_MyEvent);

                //開啟線程
                Thread th = new Thread(new ThreadStart(ct.TcpThread));
                th.IsBackground = true;
                th.Start();
            }
        }

        void ct_MyEvent(string temp)
        {

            //設(shè)置服務(wù)器端TextBox的值
            this.textBox1.Text = temp;
        }
    }

 

       Form1:(客戶端)

 

public partial class Form1 : Form
    {

        //聲明Tcp客戶端
        private TcpClient tc;

        //聲明網(wǎng)絡(luò)流
        private NetworkStream ns;
        public Form1()
        {
            CheckForIllegalCrossThreadCalls = false;
            InitializeComponent();
        }

        private void button2_Click(object sender, EventArgs e)
        {

            //注冊(cè)本機(jī)8888端口
            tc = new TcpClient("localhost",8888);

            //實(shí)例化網(wǎng)絡(luò)流對(duì)象
            ns = tc.GetStream();
            string temp = this.textBox1.Text;

            StreamWriter sw = new StreamWriter(ns);
            StreamReader sr = new StreamReader(ns);

            //將TextBox1的值傳給服務(wù)器端
            sw.WriteLine(temp);
            sw.Flush();

            //接收服務(wù)器端回傳的字符串
            string str = sr.ReadLine();
            this.textBox2.Text = str;
            sr.Close();
            sw.Close();
        }
    }

 

       ClientTcp類:

    //聲明一個(gè)需要一個(gè)字符串參數(shù)的委托

    public delegate void MyDelegate(string temp);
    class ClientTcp
    {

        //設(shè)置網(wǎng)絡(luò)流局部對(duì)象
        private NetworkStream ns;

        //聲明類型為MyDelegate的事件MyEvent
        public event MyDelegate MyEvent;

        //構(gòu)造函數(shù)中接收參數(shù)以初始化
        public ClientTcp(NetworkStream ns)
        {
            this.ns = ns;
        }

        //服務(wù)器端線程所調(diào)用的方法
        public void TcpThread()
        {

            //獲得相關(guān)的封裝流
            StreamReader sr = new StreamReader(ns);
            string temp = sr.ReadLine();

            //接收到客戶端消息后觸發(fā)事件將消息回傳
            MyEvent(temp);
            StreamWriter sw = new StreamWriter(ns);

            //轉(zhuǎn)換為大寫后發(fā)送消息給客戶端
            sw.WriteLine(temp.ToUpper());
            sw.Flush();
            sw.Close();
            sr.Close();
        }
    }

這里說下為什么需要ClientTcp這么個(gè)類,說這個(gè)之前,先說一下為什么服務(wù)器端需要開啟一個(gè)新的線程來監(jiān)控端口,這個(gè)原因比較簡(jiǎn)單,Socket sock = tl.AcceptSocket();  這個(gè)方法會(huì)造成阻塞,也就是說如果沒有得到客戶端的響應(yīng),TcpListenr將一直監(jiān)聽下去,這就會(huì)造成程序的假死,因此我們需要單獨(dú)開一個(gè)線程來監(jiān)聽我們的8888端口,我們觀察服務(wù)器端(Form2)可以看出,NetworkStream是一個(gè)全局變量(實(shí)際上局部與全局都是一樣),如果CPU忙的過來,直接把ClientTcp里的方法拿到Form2里寫沒問題,但是一旦客戶端過多造成數(shù)據(jù)擁擠,那很可能當(dāng)運(yùn)算還未結(jié)束,NetworkStream就已經(jīng)換人了,因此當(dāng)我們?nèi)〉媚晨蛻舳藢?duì)應(yīng)的NetworkStream后,應(yīng)該考慮立刻將它封裝到一個(gè)類中,再在該類中再對(duì)該NetworkStream做相應(yīng)的操作,ClientTcp這個(gè)類就是為這個(gè)設(shè)計(jì)的,而當(dāng)封裝了NetworkStream后,我們發(fā)現(xiàn)從客戶端傳過來的值是我們需要的,因此就用到了事件的回調(diào),這個(gè)我前面有篇文章里講過了,見http://blog.sina.com.cn/u/4c459776010008ws,基于TCP協(xié)議的網(wǎng)絡(luò)編程基礎(chǔ)的東西就這些,寫法很固定,但是需要很多的技巧,前幾天試著寫一個(gè)聊天室程序,差點(diǎn)沒吐血,果然不是一般的麻煩。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 日韩高清国产一区在线 | 人人射人人 | 亚洲人成在线观看 | 欧美三及片 | 男女羞羞羞视频午夜视频 | 欧美日韩国产一区二区三区不卡 | 成人毛片在线视频 | 日韩精品| 国产传媒在线视频 | 狠狠爱www人成狠狠爱综合网 | 亚洲黄色一级毛片 | 久久污视频 | 日韩av在线一区 | 久久狠狠 | 日韩精品久久 | 一级特黄网站 | 国产一区二区三区在线 | 九色在线观看视频 | 欧美激情精品久久久久久 | 欧美精品一区二区免费 | 中文字幕亚洲一区二区三区 | 米奇狠狠狠狠8877 | 久久aⅴ乱码一区二区三区 午夜在线播放 | 日韩一区二区三免费高清在线观看 | 91精品国产91久久综合桃花 | 久久精品这里有 | 精品国产一区二区三区久久影院 | 中文字幕色 | av官网在线 | 91精品国产综合久久久蜜臀图片 | 成人高清在线 | 国产一级特黄毛片在线毛片 | 欧美精品二区中文乱码字幕高清 | 麻豆精品国产传媒 | 国产一级免费看 | 日日操天天操 | 久久这里只有精品首页 | 一区二区免费看 | 中文字幕加勒比 | 91久久国产综合久久 | 在线免费看a |