在这个颜值当道,屌丝闪边的时代,拼不过颜值拼内涵,只有知识丰富才能提升一个人的内在气质和修养,所谓人丑就要多学习,今天图老师给大家分享C#实时申请技术,希望可以对大家能有小小的帮助。
【 tulaoshi.com - 编程语言 】
Real time Application 实时申请技术在本文里是作为一个实例来演示在用户(Tcpclient)申请与服务器(TcpServer)申请之间使用Socket类的情况 。该项目同样也演示在实时项目中如何使用listview控制以及如何传递XML格式信息。
TcpServer.exe 文件显示了在单独的thread当中(而不是在GUI 线程之中)TCP socket的相互通讯。
TcpClient.exe文件同样也使用一条单独的线程 从Socket中读取数据,然后对表单中的list view控件进行更新。
步聚如下:
1.TcpServer 监听端口8002,并且发射线程等待客户端连结。
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连接上后,发送客户端信息数据包至TcpServer,然后发射线程,该线程是用来接收通过Socket传来的数据。
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的连接请求,并且将socket 实例保存到Hash表中,然后发射线程以便控制socket的通讯,同时将客户端信息在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 downpublic 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. 点击Load Data菜单,从文件中载入信息,然后把所有信息传送到每个将与TcpServer相连接的客户端,客户端会自己更新它的listview。不管是TcpServer 还是 TcpClient ,它们都从运作中的线程之中获取数据,再在主线程中更新Listview control。下面则讲述的是通过MethodInvoker实现该功能。
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 charSendDataToAllClient(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);elsetmp = String.Format("", elem);return tmp;}以下功能演示的是如何设置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.FromArgb(255, 255, 175));setColColorHL(i, 0, System.Drawing.Color.FromArgb(128,0,0));setColColorHL(i, 1, System.Drawing.Color.FromArgb(128,0,0));this.listView1.Update();Thread.Sleep(300);setColColor(i, 0, System.Drawing.Color.FromArgb(255, 255,175));setColColor(i, 1, System.Drawing.Color.FromArgb(255, 255, 175));}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.FromArgb(128,0,0));setColColorHL(ind, 1, System.Drawing.Color.FromArgb(128,0,0));this.listView1.Update();Thread.Sleep(300);setColColor(ind, 0, System.Drawing.Color.FromArgb(255,255,175));setColColor(ind, 1, System.Drawing.Color.FromArgb(255,255,175));}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;elsethis.listView1.Items[rowNum].SubItems[colNum].BackColor =System.Drawing.Color.FromArgb(248, 248,248);if (colNum==0){this.listView1.Items[rowNum].SubItems[colNum].ForeColor =System.Drawing.Color.FromArgb(128, 0, 64);this.listView1.Items[rowNum].SubItems[colNum].BackColor =System.Drawing.Color.FromArgb(197, 197, 182);}elsethis.listView1.Items[rowNum].SubItems[colNum].ForeColor =System.Drawing.Color.FromArgb(20, 20,20);}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.FromArgb(255,255,255);}
运行该例子的步骤
1. 在A机上运行TcpServer.exe文件。
(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)2. 在A机或B机上运行一次或多次TcpClient.exe文件。
3. 在TcpClient端,点击菜单连接,进入TcpServer正在运行中的服务器端。在编辑栏键入用户名及口令,点击确认。
4. 当在TcpServer顶部的istview上瞧见客户端的提示时,则在TcpServer,上点击Load Data菜单,然后实时数据则会出现在TcpServer 和TcpClien上。
注意:请确认Data file, Issue.txt and Issue.xml等文件总是处于同一根目录下,正如TcpSvr.exe 和 MaskedTextBox.dll, WTcpClient.exe.是处于同一目录下一样。
(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)Update at 10/20/2001.
当添加/删除项目时,请锁住Hash表,这样可以确保线程的安全。
添加功能,以便生成和处理XML格式文件。
在发送讯息至客户端时,请在服务器端添加发送讯息起始和结尾的字符。
上述方法可以增加客户端的稳定性。
来源:http://www.tulaoshi.com/n/20160219/1614318.html