<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 56,  comments - 12,  trackbacks - 0
    Real time Application 實(shí)時(shí)申請(qǐng)技術(shù)在本文里是作為一個(gè)實(shí)例來演示在用戶(Tcpclient)申請(qǐng)與服務(wù)器(TcpServer)申請(qǐng)之間使用Socket類的情況 。該項(xiàng)目同樣也演示在實(shí)時(shí)項(xiàng)目中如何使用listview控制以及如何傳遞XML格式信息。

      TcpServer.exe 文件顯示了在單獨(dú)的thread當(dāng)中(而不是在
    GUI 線程之中)TCP socket的相互通訊。

      TcpClient.exe文件同樣也使用一條單獨(dú)的線程 從Socket中讀取數(shù)據(jù),然后對(duì)表單中的list
    view 控件進(jìn)行更新。

      步聚如下:

      1.TcpServer 監(jiān)聽端口8002,并且發(fā)射線程等待客戶端連結(jié)。

    Hashtable socketHolder = new Hashtable();

    Hashtable threadHolder = new Hashtable();

    public Form1()

    {

     // Required for Windows Form Designer support

     //

     InitializeComponent();

     tcpLsn = new TcpListener(8002);

     tcpLsn.Start();

     // tcpLsn.LocalEndpoint may have a bug, it only show 0.0.0.0:8002

     stpanel.Text = "Listen at: " + tcpLsn.LocalEndpoint.
    ToString ();

     Thread tcpThd = new Thread(new ThreadStart(WaitingForClient));

     threadHolder.
    Add (connectId, tcpThd);

     tcpThd.Start() ;

    }

     

     2. TcpClient與TcpSrv連接上后,發(fā)送客戶端信息數(shù)據(jù)包至TcpServer,然后發(fā)射線程,該線程是用來接收通過Socket傳來的數(shù)據(jù)。

    private void menuConn_Click(object sender, System.EventArgs e)

    {
     ConnectDlg myDlg = new ConnectDlg();

     myDlg.ShowDialog(this);

     if( myDlg.DialogResult==DialogResult.OK)

     {

      s = new Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp );

      IPAddress hostadd = IPAddress.Parse(myDlg.IpAdd);

      int port=Int32.Parse(myDlg.PortNum);

      IPEndPoint EPhost = new IPEndPoint(hostadd, port);

      Try

      {

       s.Connect(EPhost);

       if (s.Connected)

       {

        Byte[] bBuf;

        string buf;

        buf = String.Format("{0}:{1}", myDlg.UserName,myDlg.PassWord);

        bBuf=ASCII.GetBytes(buf);

        s.Send(bBuf, 0 , bBuf.Length,0);

        t = new Thread(new ThreadStart(StartRecieve));

        t.Start();

        sbar.Text="Ready to recieve data";

       }

      }

      catch (Exception e1)

      {

       MessageBox.Show(e1.ToString());

      }

     }

    }

    private void StartRecieve()

    {

     miv = new MethodInvoker(this.UpdateListView);

     int cnt=0;

     string tmp=null;

     Byte[] firstb= new Byte[1];

     while (true)

     {

      try

      {

       Byte[] receive = new Byte[1];

       int ret = s.Receive(receive, 1, 0);

       if (ret > 0)

       {

        switch(receive[0])

        {

         case 11: //check start message

           cnt=0;

           break;

         case 10: // check end message

           cnt=0;

           if(firstb[0] == ':')

            HandleCommand(tmp);

           else if(firstb[0] == '<')

            HandleXml(tmp);

           else

            HandleText(tmp);

            tmp=null;

            break;

           default:

            if (cnt == 0)

             firstb[0] = receive[0];

             tmp += System.Text.Encoding

             .ASCII.GetString(receive);

             cnt++;

             break;

            }

           }

        }

        catch (Exception e)

        {

         if( !s.Connected )

          {

           break;

          }

         }

       }

       t.Abort();

      }

     

     

     3.TcpServer接收來自TcpClient的連接請(qǐng)求,并且將socket 實(shí)例保存到Hash表中,然后發(fā)射線程以便控制socket的通訊,同時(shí)將客戶端信息在listview 控件中顯示出來。

    public void WaitingForClient()

    {

     while(true)

     {

      // Accept will block until someone connects

      Socket sckt = tcpLsn.AcceptSocket();

      if (connectId < 10000)

       Interlocked.Increment(ref connectId);

      Else

       connectId = 1;

       if (socketHolder.Count < MaxConnected )
     
       {

        while (socketHolder.Contains(connectId) )

        {

         Interlocked.Increment(ref connectId);

        }

       Thread td = new Thread(new ThreadStart(ReadSocket));

       lock(this)

       {

        // it is used to keep connected Sockets

        socketHolder.Add(connectId, sckt);

        // it is used to keep the active thread

        threadHolder.Add(connectId, td);

       }

       td.Start();

      }

     }

    }

    // follow function handle the communication from the clients and close the

    // socket and the thread when the socket connection is down

    public void ReadSocket()

    {

     // the connectId is keeping changed with new connection added. it can't

     // be used to keep the real connectId, the local variable realId will

     // keep the value when the thread started.

     long realId = connectId;

     int ind=-1;

     Socket s = (Socket)socketHolder[realId];

     while (true)

     {

      if(s.Connected)

      {

       Byte[] receive = new Byte[37] ;

       Try

       {

        // Receive will block until data coming

        // ret is 0 or Exception happen when Socket connection

        // is broken

        int ret=s.Receive(receive,receive.Length,0);

        if (ret > 0)

        {

         string tmp = null;

         tmp=System.Text.Encoding.ASCII.GetString(receive);

         if(tmp.Length > 0)

         {

          DateTime now1=DateTime.Now;

          String strDate;

          strDate = now1.ToShortDateString() + " " + now1.ToLongTimeString();

          ListViewItem newItem = new ListViewItem();

          string[] strArry=tmp.Split(':');

          int code = checkUserInfo(strArry[0]);

          if(code==2)

          {

           userHolder.Add(realId, strArry[0]);

           newItem.SubItems.Add(strArry[0]);

           newItem.ImageIndex = 0;

           newItem.SubItems.Add(strDate);

           this.listView2.Items.Add(newItem);

           ind=this.listView2.Items.IndexOf(newItem);

          }

          else if( code==1)

         }

       }

       else

       {

        this.listView2.Items[ind].ImageIndex=1;

        keepUser=false;

        break;

       }

      }

      catch (Exception e)

      {

       if( !s.Connected )

       {

        this.listView2.Items[ind].ImageIndex=1;

        keepUser=false;

        break;

       }

      }

     }

     }
     
     CloseTheThread(realId);

    }

    private void CloseTheThread(long realId)

    {

     socketHolder.Remove(realId);

     if(!keepUser) userHolder.Remove(realId);

      lock(this)

      {

       Thread thd = (Thread)threadHolder[realId];

       threadHolder.Remove(realId);

      }

      thd.Abort();

     }

     

     

    4. 點(diǎn)擊Load Data菜單,從文件中載入信息,然后把所有信息傳送到每個(gè)將與TcpServer相連接的客戶端,客戶端會(huì)自己更新它的listview。不管是 TcpServer 還是 TcpClient ,它們都從運(yùn)作中的線程之中獲取數(shù)據(jù),再在主線程中更新Listview control。下面則講述的是通過MethodInvoker實(shí)現(xiàn)該功能。

    public void LoadThread()

    {

    MethodInvoker mi = new MethodInvoker(this.UpdateListView);

    string tmp = null;

    StreamReader sr = File.OpenText("Issue.txt");

    while((tmp = sr.ReadLine()) !=null )

    {

    if (tmp =="")

    break;



    isu.symbol= Mid(tmp, 0, 4);

    isu.bid = Mid(tmp, 4, 5);

    isu.offer = Mid(tmp, 9, 5);

    isu.volume = Mid(tmp, 16, tmp.Length-16);



    sendMsg ="\v" + tmp + "\n"; //add send message's head and end char

    SendDataToAllClient(tmp);

    this.BeginInvoke(mi);



    JobDone.WaitOne();

    }

    sr.Close();

    fThd.Abort();

    }

    private void SendDataToAllClient(string str)

    {

    foreach (Socket s in socketHolder.Values)

    {

    if(s.Connected)

    {

    Byte[] byteDateLine=ASCII.GetBytes(str.ToCharArray());

    s.Send(byteDateLine, byteDateLine.Length, 0);

    }

    }

    }

      以下代碼 操縱XML文件,并且為客戶端生成XML文件。

    public void LoadXmlThread()

    {

    MethodInvoker miv = new MethodInvoker(this.UpdateListView);

    string tmp = null;

    string xmlString = null;



    int recordFlg = -1;

    int textCount =0;

    xmlString = "\v"+"";



    XmlTextReader tr = new XmlTextReader("issue.xml");

    while(tr.Read())

    {

    switch (tr.NodeType)

    {

    case XmlNodeType.Element:

    if (tr.Name == "Issue")

    {

    recordFlg++;

    if(recordFlg > 0)

    {

    textCount=0;

    xmlString += CreateXmlElement(

    tr.Name, 2);

    xmlString += "\n";

    SendDataToAllClient(xmlString);

    xmlString = "\v"+"
    version='1.0'?>";



    this.BeginInvoke(miv);

    JobDone.WaitOne();

    }

    }

    if (recordFlg >= 0)

    {

    xmlString += CreateXmlElement(

    tr.Name, 1);

    tmp = tr.Name;

    }



    break;

    case XmlNodeType.Text:

    switch(++textCount)

    {

    case 1:

    isu.symbol=tr.Value;

    break;

    case 2:

    isu.bid=tr.Value;

    break;

    case 3:

    isu.offer=tr.Value;

    break;

    case 4:

    isu.volume=tr.Value;

    break;

    }

    xmlString += tr.Value;

    xmlString += CreateXmlElement(tmp, 2);

    break;

    }

    }

    fThd.Abort();

    }

    string CreateXmlElement(string elem, int ord)

    {

    string tmp = null;

    if (ord == 1)

    tmp = String.Format("<{0}>", elem);

    else

    tmp = String.Format("", elem);



    return tmp;

    }


    以下功能演示的是如何設(shè)置TcpClient中Listview控件的 BackColor和 Forecolor屬性 。
    private void UpdateListView()

    {

    int ind=-1;

    for (int i=0; i < this.listView1.Items.Count;i++)

    {

    if (this.listView1.Items[i].Text == isu.symbol.ToString())

    {

    ind=i;

    break;

    }

    }

    if (ind == -1)

    {

    ListViewItem newItem new ListViewItem(isu.symbol.ToString());

    newItem.SubItems.Add(isu.bid);

    newItem.SubItems.Add(isu.offer);

    newItem.SubItems.Add(isu.volume);



    this.listView1.Items.Add(newItem);

    int i=this.listView1.Items.IndexOf(newItem);

    setRowColor(i, System.Drawing.Color.FromA#ffffaf);

    setColColorHL(i, 0, System.Drawing.Color.FromA#800000);

    setColColorHL(i, 1, System.Drawing.Color.FromA#800000);

    this.listView1.Update();

    Thread.Sleep(300);

    setColColor(i, 0, System.Drawing.Color.FromA#ffffaf);

    setColColor(i, 1, System.Drawing.Color.FromA#ffffaf);

    }

    else

    {

    this.listView1.Items[ind].Text = isu.symbol.ToString();

    this.listView1.Items[ind].SubItems[1].Text = (isu.bid);

    this.listView1.Items[ind].SubItems[2].Text = (isu.offer);

    this.listView1.Items[ind].SubItems[3].Text = (isu.volume);

    setColColorHL(ind, 0, System.Drawing.Color.FromA#800000);

    setColColorHL(ind, 1, System.Drawing.Color.FromA#800000);

    this.listView1.Update();

    Thread.Sleep(300);

    setColColor(ind, 0, System.Drawing.Color.FromA#ffffaf);

    setColColor(ind, 1, System.Drawing.Color.FromA#ffffaf);

    }

    JobDone.Set();

    }



    private void setRowColor(int rowNum, Color colr )

    {

    for (int i=0; i < this.listView1.Items[rowNum].SubItems.Count;i++)

    if (rowNum%2 !=0)

    this.listView1.Items[rowNum].SubItems[i].BackColor = colr;

    }



    private void setColColor(int rowNum, int colNum, Color colr )

    {

    if (rowNum%2 !=0)

    this.listView1.Items[rowNum].SubItems[colNum].BackColor=colr;

    else

    this.listView1.Items[rowNum].SubItems[colNum].BackColor =

    System.Drawing.Color.FromA#f8f8f8;

    if (colNum==0)

    {

    this.listView1.Items[rowNum].SubItems[colNum].ForeColor =

    System.Drawing.Color.FromA#800040;

    this.listView1.Items[rowNum].SubItems[colNum].BackColor =

    System.Drawing.Color.FromA#c5c5b6;

    }

    else

    this.listView1.Items[rowNum].SubItems[colNum].ForeColor =

    System.Drawing.Color.FromA#141414;

    }



    private void setColColorHL(int rowNum, int colNum, Color colr )

    {

    this.listView1.Items[rowNum].SubItems[colNum].BackColor = colr;

    this.listView1.Items[rowNum].SubItems[colNum].ForeColor =

    System.Drawing.Color.FromA#ffffff;

    }

      運(yùn)行該例子的步驟

      1. 在A機(jī)上運(yùn)行TcpServer.exe文件。

      2. 在A機(jī)或B機(jī)上運(yùn)行一次或多次TcpClient.exe文件。

      3. 在TcpClient端,點(diǎn)擊菜單連接,進(jìn)入TcpServer正在運(yùn)行中的服務(wù)器端。在編輯欄鍵入用戶名及口令,點(diǎn)擊確認(rèn)。

      4. 當(dāng)在TcpServer頂部的istview上瞧見客戶端的提示時(shí),則在TcpServer,上點(diǎn)擊Load Data菜單,然后實(shí)時(shí)數(shù)據(jù)則會(huì)出現(xiàn)在TcpServer 和TcpClien上。

      注意:請(qǐng)確認(rèn)Data file, Issue.txt and Issue.xml等文件總是處于同一根目錄下,正如TcpSvr.exe 和 MaskedTextBox.dll, WTcpClient.exe.是處于同一目錄下一樣。

      Update at 10/20/2001.

      當(dāng)添加/刪除項(xiàng)目時(shí),請(qǐng)鎖住Hash表,這樣可以確保線程的安全。

      添加功能,以便生成和處理XML格式文件。

      在發(fā)送訊息至客戶端時(shí),請(qǐng)?jiān)诜?wù)器端添加發(fā)送訊息起始和結(jié)尾的字符。

      上述方法可以增加客戶端的穩(wěn)定性。


    苦笑枯 2007-01-19 00:13 發(fā)表評(píng)論

    文章來源:http://www.tkk7.com/kuxiaoku/articles/94803.html
    posted on 2007-01-19 00:13 苦笑枯 閱讀(223) 評(píng)論(0)  編輯  收藏 所屬分類: C#
    收藏來自互聯(lián)網(wǎng),僅供學(xué)習(xí)。若有侵權(quán),請(qǐng)與我聯(lián)系!

    <2007年1月>
    31123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    常用鏈接

    留言簿(2)

    隨筆分類(56)

    隨筆檔案(56)

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 99久久99久久精品免费看蜜桃| 国产a不卡片精品免费观看 | 亚洲国产成人久久精品app| 台湾一级毛片永久免费| 小说区亚洲自拍另类| 中文字幕亚洲乱码熟女一区二区| 野花香高清视频在线观看免费| 亚洲人色大成年网站在线观看| 国产高清免费的视频| 久久久久久久久久久免费精品 | 日韩亚洲变态另类中文| 99久久99久久免费精品小说| 亚洲乱码在线观看| 日韩一卡2卡3卡4卡新区亚洲| 九九精品免费视频| CAOPORN国产精品免费视频| 亚洲一区二区免费视频| 国产gv天堂亚洲国产gv刚刚碰| 日本zzzzwww大片免费| 一级成人a做片免费| 亚洲午夜成激人情在线影院| 久久久久亚洲精品中文字幕| 青青视频观看免费99| 国产在线播放线91免费| 亚洲精品中文字幕| 久久亚洲精品成人无码网站| 免费一区二区三区四区五区| 亚洲一区二区免费视频| 国产免费人成视频在线播放播| 亚洲精品色播一区二区| 久久精品国产亚洲AV高清热 | 性色午夜视频免费男人的天堂 | 久久精品成人免费国产片小草| 国产亚洲sss在线播放| 国产亚洲美女精品久久久久狼| 成人爽A毛片免费看| 污污网站18禁在线永久免费观看| 老司机福利在线免费观看| 亚洲真人无码永久在线观看| 亚洲综合在线观看视频| 亚洲中文字幕不卡无码|