C#实现TCP通讯协议

本人小白一个,初次使用C#,希望各位大神对小白不足之处能指点一下,O(∩_∩)O谢谢

项目需求:公司锡膏室有四台冰箱,需要对该四台冰箱的温湿度实时采集同时以曲线图方式Show到一块看板上

思路:1,需要将设备发送的数据实时存储至数据库(使用TCP通讯协议实时抓取数据)

         2,将数据以曲线图方式Show至看板上(需要使用到AJAX以及强大的JS库【ECharts】})

一,实现数据抓取并存储至数据库

代码如下:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Data.SqlClient;
  6 using System.Drawing;
  7 using System.IO;
  8 
  9 using System.Net;
 10 using System.Net.Sockets;
 11 using System.Text;
 12 using System.Threading;
 13 
 14 using System.Windows.Forms;
 15 
 16 namespace WindowsFormsApplication1
 17 {
 18     public partial class Form1 : Form
 19     {
 20         public Form1()
 21         {
 22             InitializeComponent();
 23             TextBox.CheckForIllegalCrossThreadCalls = false;
 24         }
 25         Thread threadWatch = null; // 负责监听客户端连接请求的 线程;
 26         Socket socketWatch = null;
 27 
 28         Dictionary<string, Socket> dict = new Dictionary<string, Socket>();
 29         Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>();
 30 
 31         /// <summary>
 32         /// 啟動監控服務
 33         /// </summary>
 34         /// <param name="sender"></param>
 35         /// <param name="e"></param>
 36         private void button1_Click(object sender, EventArgs e)
 37         {
 38             // 创建负责监听的套接字,注意其中的参数;
 39             socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 40             // 获得文本框中的IP对象;
 41             IPAddress address = IPAddress.Parse(textBox1.Text.Trim());
 42             // 创建包含ip和端口号的网络节点对象;
 43             IPEndPoint endPoint = new IPEndPoint(address, int.Parse(textBox2.Text.Trim()));
 44             try
 45             {
 46                 // 将负责监听的套接字绑定到唯一的ip和端口上;
 47                 socketWatch.Bind(endPoint);
 48             }
 49             catch (SocketException se)
 50             {
 51                 MessageBox.Show("异常:" + se.Message);
 52                 return;
 53             }
 54             // 设置监听队列的长度;
 55             socketWatch.Listen(10);
 56             // 创建负责监听的线程;
 57             threadWatch = new Thread(WatchConnecting);
 58             threadWatch.IsBackground = true;
 59             threadWatch.Start();
 60             ShowMsg("服务器启动监听成功!");
 61         }
 62 
 63         /// <summary>
 64         /// 监听客户端请求的方法;
 65         /// </summary>
 66         void WatchConnecting()
 67         {
 68             while (true)  // 持续不断的监听客户端的连接请求;
 69             {
 70                 // 开始监听客户端连接请求,Accept方法会阻断当前的线程;
 71                 Socket sokConnection = socketWatch.Accept(); // 一旦监听到一个客户端的请求,就返回一个与该客户端通信的 套接字;
 72                 // 想列表控件中添加客户端的IP信息;
 73                 listBox1.Items.Add(sokConnection.RemoteEndPoint.ToString());
 74                 // 将与客户端连接的 套接字 对象添加到集合中;
 75                 dict.Add(sokConnection.RemoteEndPoint.ToString(), sokConnection);
 76                 ShowMsg("客户端连接成功!");
 77                 Thread thr = new Thread(RecMsg);
 78                 thr.IsBackground = true;
 79                 thr.Start(sokConnection);
 80                 dictThread.Add(sokConnection.RemoteEndPoint.ToString(), thr);  //  将新建的线程 添加 到线程的集合中去。
 81             }
 82         }
 83 
 84 
 85         void RecMsg(object sokConnectionparn)
 86         {
 87             Socket sokClient = sokConnectionparn as Socket;
 88             while (true)
 89             {
 90                 // 定义一个2M的缓存区;
 91                 byte[] arrMsgRec = new byte[1024 * 1024 * 2];
 92                 // 将接受到的数据存入到输入  arrMsgRec中;
 93                 int length = -1;
 94                 try
 95                 {
 96                     length = sokClient.Receive(arrMsgRec); // 接收数据,并返回数据的长度;
 97                 }
 98                 catch (SocketException se)
 99                 {
100                     ShowMsg("异常:" + se.Message);
101                     // 从 通信套接字 集合中删除被中断连接的通信套接字;
102                     dict.Remove(sokClient.RemoteEndPoint.ToString());
103                     // 从通信线程集合中删除被中断连接的通信线程对象;
104                     dictThread.Remove(sokClient.RemoteEndPoint.ToString());
105                     // 从列表中移除被中断的连接IP
106                     listBox1.Items.Remove(sokClient.RemoteEndPoint.ToString());
107                     break;
108                 }
109                 catch (Exception e)
110                 {
111                     ShowMsg("异常:" + e.Message);
112                     // 从 通信套接字 集合中删除被中断连接的通信套接字;
113                     dict.Remove(sokClient.RemoteEndPoint.ToString());
114                     // 从通信线程集合中删除被中断连接的通信线程对象;
115                     dictThread.Remove(sokClient.RemoteEndPoint.ToString());
116                     // 从列表中移除被中断的连接IP
117                     listBox1.Items.Remove(sokClient.RemoteEndPoint.ToString());
118                     break;
119                 }
120                 
121                 ///--------------------------------------接收客戶端發送過來的信息----------------------------------------------
122                     string strMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec, 1, length - 1);// 将接受到的字节数据转化成字符串;
123                     ShowMsg(strMsg);
124 
125 
126                     ///------------------------------------向客戶端發送回執信息--------------------------------------
127                     string WD = strMsg.Substring(42, 4);
128                     string SD = strMsg.Substring(47, 4);
129                     string Mdl = strMsg.Substring(21, 10);
130                     string ZOOM = strMsg.Substring(32, 1);
131                     string SendTime = "20" + strMsg.Substring(3, 17) + ":000";
132                     if (Mdl == "0072916200") { Mdl = "冰箱-01"; }
133                     else if (Mdl == "0072915200") { Mdl = "冰箱-03"; }
134                     else if (Mdl == "0072914500") { Mdl = "冰箱-04"; }
135                     else if (Mdl == "0072912300") { Mdl = "冰箱-02"; }
136                     SqlConnection sqlcon = new SqlConnection("Data Source=10.99.106.***;Initial Catalog=PCA_REPORT;User ID=***;pwd=***");
137                     string addx = "INSERT INTO PCA_REPORT..Temperature VALUES ('" + Mdl + "','" + WD + "','" + SD + "','" + SendTime + "',getdate(),'" + ZOOM + "')";
138                     DataSet ds = new DataSet();
139                     SqlDataAdapter adapter = new SqlDataAdapter(addx, sqlcon);
140                     adapter.Fill(ds);
141                    
142                     string send = "*RR," + strMsg.Substring(3, 17) + "," + strMsg.Substring(21, 10) + "#";
143                    
144 
145 
146                     byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(send); // 将要发送的字符串转换成Utf-8字节数组;
147                     byte[] arrSendMsg = new byte[arrMsg.Length + 1];
148                     arrSendMsg[0] = 0; // 表示发送的是消息数据
149                     Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);    
150                     for (int i = 0; i < listBox1.Items.Count; i++)
151                     {
152                         string strKey = listBox1.Items[i].ToString();
153                        
154                             dict[strKey].Send(arrSendMsg);// 解决了 sokConnection是局部变量,不能再本函数中引用的问题;
155                             //ShowMsg(send);
156 
157                       
158                     }
159                   
160             }
161         }
162 
163 
164 
165         void ShowMsg(string str)
166         {
167             textBox5.AppendText(str + "\r\n");
168         }
169 
170         private void label2_Click(object sender, EventArgs e)
171         {
172 
173         }
174        
175     }
176 }

1,将设备与该程式设置为同一网段IP

2,将设备IP指向与当前程式运行的IP(以上程式表明设备指向的IP是:192.168.1.130,指向端口是:9438)

设置以上后,程式就可以接受设备传输的数据了

运行之后如下图:

 

二,实现将数据以曲线图方式实时Show至看板上

可跳转至:https://download.csdn.net/download/bibabu135766/10274321

看板效果如下图:

 

posted @ 2018-04-11 19:09  毕吧卟  阅读(15938)  评论(0编辑  收藏  举报