找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 10118|回复: 17
打印 上一主题 下一主题
收起左侧

c#写的tcp/ip服务端与客户端源码和资料下载

  [复制链接]
跳转到指定楼层
楼主
服务端运行界面:

客户端云心界面:




全部资料51hei下载地址:
2、TCP_IP.rar (5.74 MB, 下载次数: 355)


源码预览:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;

  9. //添加的引用
  10. using System.Net;
  11. using System.Net.Sockets;
  12. using System.Threading;
  13. using System.IO;
  14. using System.Threading.Tasks;
  15. using System.Collections;

  16. namespace TCP_IP
  17. {
  18.     public partial class Form1 : Form
  19.     {
  20.         //socket
  21.         /*public Socket newclient;//新建socket连接口
  22.         public bool Connected;
  23.         public Thread myThread;
  24.         public delegate void MyInvoke(string str);
  25.         public IPEndPoint myIe;
  26.         public IPAddress myIp;
  27.         public int myPort;*/
  28.         public delegate void MyInvoke(string str);
  29.         MyTcpServer cMyTcpServer = new MyTcpServer();

  30.         MySession cMySession = new MySession();// { TcpSocket = cMyTcpServer.GetType() };
  31.         //send or receive
  32.         public byte[] myBy;//传递串口接收到的数据
  33.         public int myByLenth = 0;//串口接收到的数据长度
  34.         public string myStr;//串口接收的字符串
  35.         public bool receiveDtatFlag = false;

  36.         public bool myCloseForm = false;//防止窗口关闭时线程没有关闭占用资源

  37.         public bool myThreadStop = true;
  38.         public int send_count = 0;
  39.         public int recv_count = 0;

  40.         public Form1()
  41.         {
  42.             InitializeComponent();
  43.         }
  44.         #region 窗体处理
  45.         private void Form1_Load(object sender, EventArgs e)//页面加载
  46.         {
  47.             myCloseForm = false;
  48.             //checkBox1.Checked = true;
  49.             checkBox2.Checked = true;
  50.             checkBox3.Checked = true;
  51.             //checkBox4.Checked = true;
  52.             button1.Visible = false;

  53.             Thread myThread = new Thread(ReceiveMsg);//创建新线程
  54.             myThread.IsBackground = true;//线程后台运行
  55.             myThread.Start();//启动线程
  56.         }

  57.         private void Form1_FormClosing(object sender, FormClosingEventArgs e)//退出窗口处理
  58.         {
  59.             if (DialogResult.Yes == MessageBox.Show("程序正在使用中,确认退出?", "确认退出", MessageBoxButtons.YesNo))
  60.             {
  61.                 myCloseForm = true;
  62.                 this.Dispose();
  63.                 System.Environment.Exit(System.Environment.ExitCode);
  64.                 this.Close();
  65.                 e.Cancel = false;
  66.             }
  67.             else
  68.             {
  69.                 e.Cancel = true;
  70.             }
  71.         }

  72.         private void button1_Click(object sender, EventArgs e)//隐藏该窗口
  73.         {
  74.             this.Hide();
  75.         }
  76.         #endregion

  77.         #region 连接按钮处理
  78.         public void myConnect()//开启连接
  79.         {
  80.             //byte[] data = new byte[1024];
  81.             if (btnConnect.Text.Trim() == "启动侦听")
  82.             {
  83.                 btnConnect.Text = "断开连接";
  84.                 this.pictureBox1.Image = Image.FromFile(Application.StartupPath + "\\green.png");//bin文件中
  85.                 txbServerIP.Enabled = false;
  86.                 txbServerPort.Enabled = false;
  87.                 cMyTcpServer.OpenServer(Convert.ToInt32(txbServerPort.Text.Trim()));               
  88.             }
  89.             else
  90.             {
  91.                 btnConnect.Text = "启动侦听";
  92.                 this.pictureBox1.Image = Image.FromFile(Application.StartupPath + "\\red.png");//bin文件中
  93.                 txbServerIP.Enabled = true;
  94.                 txbServerPort.Enabled = true;
  95.                 cMyTcpServer.CloseServer();
  96.             }

  97.             /*if (Connected == false)//没有连接
  98.             {
  99.                 newclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  100.                 myIp = IPAddress.Parse(txbServerIP.Text.Trim());
  101.                 myPort = Convert.ToInt32(txbServerPort.Text.Trim());
  102.                 myIe = new IPEndPoint(myIp, myPort);

  103.                 try
  104.                 {
  105.                     newclient.Connect(myIe);
  106.                     //btnConnect.Enabled = false;
  107.                     Connected = true;
  108.                     btnConnect.Text = "断开连接";
  109.                     myThreadStop = true;
  110.                     this.pictureBox1.Image = Image.FromFile(Application.StartupPath + "\\green.png");//bin文件中
  111.                     txbServerIP.Enabled = false;
  112.                     txbServerPort.Enabled = false;
  113.                 }
  114.                 catch (SocketException e)
  115.                 {
  116.                     Connected = false;
  117.                     btnConnect.Text = "连接服务器";
  118.                     myThreadStop = false;
  119.                      this.pictureBox1.Image = Image.FromFile(Application.StartupPath + "\\red.png");//bin文件中
  120.                     txbServerIP.Enabled = true;
  121.                     txbServerPort.Enabled = true;
  122.                     MessageBox.Show("连接服务器失败  " + e.Message);
  123.                     return;
  124.                 }

  125.                 //多线程处理

  126.                 //ThreadStart myThreaddelegate = new ThreadStart(ReceiveMsg);
  127.                 //myThread = new Thread(myThreaddelegate);

  128.                 Thread myThread = new Thread(ReceiveMsg);//创建新线程
  129.                 myThread.IsBackground = true;//线程后台运行
  130.                 myThread.Start();//启动线程
  131.             }
  132.             else
  133.             {
  134.                 Connected = false;
  135.                 btnConnect.Text = "连接服务器";
  136.                 this.pictureBox1.Image = Image.FromFile(Application.StartupPath + "\\red.png");//bin文件中
  137.                 if (myThread != null)
  138.                 {
  139.                     myThread.Abort();
  140.                     //Application.ExitThread();
  141.                 }
  142.                 myThreadStop = false;
  143.                 newclient.Disconnect(false);
  144.                 txbServerIP.Enabled = true;
  145.                 txbServerPort.Enabled = true;
  146.             }*/

  147.         }

  148.         private void btnConnect_Click(object sender, EventArgs e)//开启连接
  149.         {
  150.             myConnect();
  151.         }
  152.         #endregion


  153.         ///////////////////数据多线程处理部分//////20170919////////////////////////////     
  154.         #region 真正使用的接收线程处理部分
  155.         public void ReceiveMsg()//接收处理线程部分
  156.         {
  157.             while (myThreadStop)
  158.             {
  159.                 string myRecvStrTemp = "";
  160.                 #region
  161.                 lock (cMyTcpServer.dic_ClientSocket)
  162.                 {
  163.                     foreach (var item in cMyTcpServer.dic_ClientSocket)
  164.                     {
  165.                         //cMySession = item.Value;//两种方法都可以
  166.                         if (cMyTcpServer.dic_ClientSocket.TryGetValue(item.Key.ToString(), out cMySession) == true)
  167.                         {
  168.                             byte[] myReceByte = cMySession.GetBuffer(0,cMySession.m_Buffer.Count);//提取接收数据

  169.                             //数据处理
  170.                             if (myReceByte.Length > 0)
  171.                             {
  172.                                 StringBuilder builder = new StringBuilder();//避免在事件处理方法中反复的创建,定义到外面。
  173.                                 long received_count = 0;//接收计数                    
  174.                                 received_count += myReceByte.Length;//增加接收计数
  175.                                 builder.Clear();//清除字符串构造器的内容

  176.                                 myBy = myReceByte;
  177.                                 myByLenth = myReceByte.Length;
  178.                                 if (checkBox3.Checked)//接收时间显示
  179.                                 {
  180.                                     if (chbRecvIpPort.Checked)//接收IP和端口显示
  181.                                     {
  182.                                         myRecvStrTemp += DateTime.Now.ToString("yyyy-MM-dd") + " " + DateTime.Now.ToString(@"HH\:mm\:ss\:fff") + " " + cMySession.GetIp() + "\n";
  183.                                     }
  184.                                     else
  185.                                     {
  186.                                         myRecvStrTemp += DateTime.Now.ToString("yyyy-MM-dd") + " " + DateTime.Now.ToString(@"HH\:mm\:ss\:fff") + "\n";
  187.                                     }

  188.                                 }
  189.                                 else
  190.                                 {
  191.                                     if (chbRecvIpPort.Checked)//接收IP和端口显示
  192.                                     {
  193.                                         myRecvStrTemp += cMySession.GetIp() + "\n";
  194.                                     }
  195.                                 }
  196.                                 //判断是否是显示为16禁止
  197.                                 if (checkBox1.Checked)
  198.                                 {
  199.                                     //依次的拼接出16进制字符串
  200.                                     foreach (byte b in myReceByte)
  201.                                     {
  202.                                         builder.Append(b.ToString("X2") + " ");//在此实例的结尾追加指定字符串的副本
  203.                                     }
  204.                                 }
  205.                                 else
  206.                                 {
  207.                                     //直接按ASCII规则转换成字符串
  208.                                     builder.Append(Encoding.ASCII.GetString(myReceByte));
  209.                                 }
  210.                                 //追加的形式添加到文本框末端,并滚动到最后。
  211.                                 myRecvStrTemp += builder.ToString();
  212.                                 myStr = builder.ToString();//字符串输出

  213.                                 if (checkBox2.Checked)//接收换行显示
  214.                                 {
  215.                                     myRecvStrTemp += "\n";
  216.                                 }
  217.                                 try
  218.                                 {
  219.                                     if (receiveDtatFlag == true)//保存数据
  220.                                     {
  221.                                         string fName = saveFileDialog1.FileName;
  222.                                         FileStream fs = File.Open(fName, FileMode.Append);
  223.                                         StreamWriter sw = new StreamWriter(fs);

  224.                                         if (checkBox3.Checked)//接收时间显示
  225.                                         {
  226.                                             sw.Write(DateTime.Now.ToString("yyyy-MM-dd") + " ");
  227.                                             sw.Write(DateTime.Now.ToString(@"HH\:mm\:ss\:fff") + "\n");
  228.                                         }
  229.                                         sw.Write(builder.ToString());
  230.                                         if (checkBox2.Checked)//接收换行显示
  231.                                         {
  232.                                             sw.WriteLine("\n");

  233.                                         }
  234.                                         sw.Close();
  235.                                         fs.Close();
  236.                                     }
  237.                                 }
  238.                                 catch
  239.                                 {

  240.                                 }
  241.                                 recv_count += myReceByte.Length;//增加接收计数
  242.                             }                           
  243.                         }
  244.                         //cMySession = item.Value;//两种方法都可以

  245.                     }
  246.                 }
  247.                 #endregion
  248.                 showMsg(myRecvStrTemp);
  249.             }
  250.         }
  251.         public void showMsg(string msg)//接收显示处理部分
  252.         {
  253.             {
  254.                 //在线程里以安全方式调用控件
  255.                 if ((rtbReceiveMsg.InvokeRequired) || (txbRecvCount.InvokeRequired))
  256.                 {
  257.                     MyInvoke _myinvoke = new MyInvoke(showMsg);
  258.                     rtbReceiveMsg.Invoke(_myinvoke, new object[] { msg });
  259.                 }
  260.                 else
  261.                 {
  262.                     rtbReceiveMsg.AppendText(msg);//显示部分
  263.                     txbRecvCount.Text = recv_count.ToString();
  264.                 }
  265.             }
  266.         }//*/

  267.         private void rtbReceiveMsg_TextChanged(object sender, EventArgs e)//接收窗处理
  268.         {
  269.             if (rtbReceiveMsg.Lines.Length > 8000)//大于8000行时清楚前面的
  270.             {
  271.                 int n = 500;
  272.                 int start = rtbReceiveMsg.GetFirstCharIndexFromLine(0);//第一行第一个字符索引
  273.                 int end = rtbReceiveMsg.GetFirstCharIndexFromLine(n);//第n行第一个字符索引
  274.                 rtbReceiveMsg.Select(start, end);//选中n行
  275.                 rtbReceiveMsg.SelectedText = "";//设置前n行为空

  276.             }
  277.             rtbReceiveMsg.Focus();
  278.             rtbReceiveMsg.Select(rtbReceiveMsg.TextLength, 0);
  279.         }

  280.         private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)//清除接收窗数据
  281.         {
  282.             rtbReceiveMsg.Text = "";
  283.             send_count = 0;
  284.             textBox4.Text = "";
  285.             txbRecvCount.Text = "";
  286.         }
  287.         #endregion              

  288.         #region 数据发送处理
  289.         private void btnMySendMessage_Click(object sender, EventArgs e)//发送数据
  290.         {
  291.             try
  292.             {
  293.                 if (checkBox5.Checked == true)
  294.                 {
  295.                     timer1.Enabled = true;
  296.                 }
  297.                 else
  298.                 {
  299.                     timer1.Enabled = false;
  300.                 }
  301.                 //string s = "";                    
  302.                 if (checkBox4.Checked)//十六进制发送
  303.                 {
  304.                     ArrayList al = cMyMathClass.Str16ToArrayList(rtbMySendMessage.Text);
  305.                     byte[] by = new byte[al.Count];
  306.                     int i = 0;
  307.                     foreach (string stmp in al)
  308.                     {
  309.                         by[i] += Convert.ToByte(stmp, 16);//将指定基的数字的字符串表示形式转换为等效的 8 位无符号整数。
  310.                         i++;
  311.                     }
  312.                     //int mySendLenth = newclient.Send(by);
  313.                     lock (cMyTcpServer.dic_ClientSocket)
  314.                     {
  315.                         foreach (var item in cMyTcpServer.dic_ClientSocket)
  316.                         {
  317.                             cMyTcpServer.SendData(item.Key.ToString(), by);
  318.                         }
  319.                     }
  320.                     //serialPort1.Write(by, 0, i);//发送字节
  321.                     //s = Encoding.GetEncoding("Gb2312").GetString(by);//在派生类中重写时,将指定字节数组中的所有字节解码为一个字符串。。
  322.                 }
  323.                 else//ASCII发送
  324.                 {
  325.                     int m_length = rtbMySendMessage.Text.Trim().Length;
  326.                     byte[] data = new byte[m_length];
  327.                     data = Encoding.UTF8.GetBytes(rtbMySendMessage.Text);
  328.                     lock (cMyTcpServer.dic_ClientSocket)
  329.                     {
  330.                         foreach (var item in cMyTcpServer.dic_ClientSocket)
  331.                         {
  332.                             cMyTcpServer.SendData(item.Key.ToString(), data);
  333.                         }
  334.                     }
  335.                     //int mySendLenth = newclient.Send(data);

  336.                 }
  337.                 send_count++;
  338.             }
  339.             catch (Exception)
  340.             {
  341.                 MessageBox.Show("发送数据时发生错误!", "错误提示");
  342.             }            
  343.         }

  344.         private void timer1_Tick(object sender, EventArgs e)//定时发送
  345.         {
  346.             timer1.Interval = Convert.ToInt32(textBox1.Text);
  347.             try
  348.             {
  349.                 if (checkBox5.Checked == true)
  350.                 {                  
  351.                     if (checkBox4.Checked)//十六进制发送
  352.                     {
  353.                         ArrayList al = cMyMathClass.Str16ToArrayList(rtbMySendMessage.Text);
  354.                         byte[] by = new byte[al.Count];
  355.                         int i = 0;
  356.                         foreach (string stmp in al)
  357.                         {
  358.                             by[i] += Convert.ToByte(stmp, 16);//将指定基的数字的字符串表示形式转换为等效的 8 位无符号整数。
  359.                             i++;
  360.                         }
  361.                         //int mySendLenth = newclient.Send(by);
  362.                         lock (cMyTcpServer.dic_ClientSocket)
  363.                         {
  364.                             foreach (var item in cMyTcpServer.dic_ClientSocket)
  365.                             {
  366.                                 cMyTcpServer.SendData(item.Key.ToString(), by);
  367.                             }
  368.                         }
  369.                         //serialPort1.Write(by, 0, i);//发送字节
  370.                         //s = Encoding.GetEncoding("Gb2312").GetString(by);//在派生类中重写时,将指定字节数组中的所有字节解码为一个字符串。。
  371.                     }
  372.                     else//ASCII发送
  373.                     {
  374.                         int m_length = rtbMySendMessage.Text.Trim().Length;
  375.                         byte[] data = new byte[m_length];
  376.                         data = Encoding.UTF8.GetBytes(rtbMySendMessage.Text);
  377.                         lock (cMyTcpServer.dic_ClientSocket)
  378.                         {
  379.                             foreach (var item in cMyTcpServer.dic_ClientSocket)
  380.                             {
  381.                                 cMyTcpServer.SendData(item.Key.ToString(), data);
  382.                             }
  383.                         }
  384.                         //int mySendLenth = newclient.Send(data);

  385.                     }
  386.                     send_count++;
  387.                 }
  388.             }
  389.             catch (Exception)
  390.             {
  391.                 MessageBox.Show("发送数据时发生错误!", "错误提示");
  392.             }            
  393.         }

  394.         private void checkBox5_CheckedChanged(object sender, EventArgs e)//自动发送区处理
  395.         {
  396.             if (checkBox4.CheckState == CheckState.Checked)//发送HEX显示
  397.             {

  398.             }
  399.             else//发送ASCII显示
  400.             {
  401.                 timer1.Enabled = false;
  402.             }
  403.         }

  404.         private void checkBox4_CheckedChanged(object sender, EventArgs e)//发送HEX区处理
  405.         {
  406.             string s = "";
  407.             if (checkBox4.CheckState == CheckState.Checked)//发送HEX显示
  408.             {
  409.                 byte[] by = Encoding.GetEncoding("Gb2312").GetBytes(rtbMySendMessage.Text);
  410.                 rtbMySendMessage.Text = "";
  411.                 foreach (byte btmp in by)
  412.                 {
  413.                     s = "00" + string.Format("{0:X}", btmp);
  414.                     rtbMySendMessage.Text += s.Substring(s.Length - 2, 2);
  415.                     rtbMySendMessage.Text += " ";
  416.                 }
  417.             }
  418.             else//发送ASCII显示
  419.             {
  420.                 ArrayList al = cMyMathClass.Str16ToArrayList(rtbMySendMessage.Text);
  421.                 byte[] by = new byte[al.Count];
  422.                 int i = 0;
  423.                 foreach (string stmp in al)
  424.                 {
  425.                     by[i] += Convert.ToByte(stmp, 16);
  426.                     i++;
  427.                 }
  428.                 rtbMySendMessage.Text = Encoding.GetEncoding("Gb2312").GetString(by);
  429.             }
  430.         }


  431.         #endregion

  432.         #region 数据保存处理
  433.         private void checkBox6_CheckedChanged(object sender, EventArgs e)//保存勾选
  434.         {
  435.             if (checkBox6.CheckState == CheckState.Checked)//选中
  436.             {
  437.                 receiveDtatFlag = true;
  438.             }
  439.             else
  440.             {
  441.                 receiveDtatFlag = false;
  442.             }


  443.         }

  444.         private void button4_Click(object sender, EventArgs e)//保存按钮
  445.         {

  446.             saveFileDialog1.Filter = "文本文件(*.txt)|*.txt";
  447.             saveFileDialog1.FilterIndex = 1;
  448.             saveFileDialog1.FileName = "ReceiveData";
  449.             if (saveFileDialog1.ShowDialog() == DialogResult.OK)
  450.             {
  451.                 string fName = saveFileDialog1.FileName;
  452.                 FileStream fs = File.Open(fName, FileMode.Append);
  453.                 StreamWriter sw = new StreamWriter(fs);
  454.                 //sw.WriteLine(richTextBox1.Text);
  455.                 textBox3.Text = fName;
  456.                 sw.Close();
  457.                 fs.Close();
  458.             }
  459.         }
  460.         #endregion            

  461.         ////////////////////外部调用接口///////////////
  462.         #region 外部调用的发送接口
  463.         public void mySendDataHandle(string mySendDataIn)
  464.         {
  465.             try
  466.             {
  467.                 if (checkBox4.Checked)//十六进制发送
  468.                 {
  469.                     ArrayList al = cMyMathClass.Str16ToArrayList(rtbMySendMessage.Text);
  470.                     byte[] by = new byte[al.Count];
  471.                     int i = 0;
  472.                     foreach (string stmp in al)
  473.                     {
  474.                         by[i] += Convert.ToByte(stmp, 16);//将指定基的数字的字符串表示形式转换为等效的 8 位无符号整数。
  475.                         i++;
  476.                     }
  477.                     //int mySendLenth = newclient.Send(by);
  478.                     lock (cMyTcpServer.dic_ClientSocket)
  479.                     {
  480.                         foreach (var item in cMyTcpServer.dic_ClientSocket)
  481.                         {
  482.                             cMyTcpServer.SendData(item.Key.ToString(), by);
  483.                         }
  484.                     }
  485.                     //serialPort1.Write(by, 0, i);//发送字节
  486.                     //s = Encoding.GetEncoding("Gb2312").GetString(by);//在派生类中重写时,将指定字节数组中的所有字节解码为一个字符串。。
  487.                 }
  488.                 else//ASCII发送
  489.                 {
  490.                     int m_length = rtbMySendMessage.Text.Trim().Length;
  491.                     byte[] data = new byte[m_length];
  492.                     data = Encoding.UTF8.GetBytes(rtbMySendMessage.Text);
  493.                     lock (cMyTcpServer.dic_ClientSocket)
  494.                     {
  495.                         foreach (var item in cMyTcpServer.dic_ClientSocket)
  496.                         {
  497.                             cMyTcpServer.SendData(item.Key.ToString(), data);
  498.                         }
  499.                     }
  500.                     //int mySendLenth = newclient.Send(data);

  501.                 }
  502.                 send_count++;

  503.             }
  504.             catch (Exception)
  505.             {
  506.                 MessageBox.Show("发送数据时发生错误!", "错误提示");
  507.             }
  508.         }//*/
  509.         #endregion
  510.     }
  511. }
复制代码


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:390264 发表于 2018-9-13 13:04 | 只看该作者
太需要了    谢谢分享
回复

使用道具 举报

板凳
ID:73991 发表于 2018-9-17 15:58 | 只看该作者
厉害,没想到在这找到了。。。。CDSN下载都是要积分,这里好多了
回复

使用道具 举报

地板
ID:462523 发表于 2019-1-5 16:04 | 只看该作者
感谢分享,需要这样的精神,谢谢
回复

使用道具 举报

5#
ID:468315 发表于 2019-1-16 13:16 | 只看该作者
感谢分享,已经下载了,正在学习中,最近刚好手头上要做一个硬件与服务器连接测试,走的也是TCP协议的,太实用了
回复

使用道具 举报

6#
ID:48097 发表于 2019-3-4 14:10 | 只看该作者
学习一下
回复

使用道具 举报

7#
ID:332109 发表于 2019-6-3 14:37 | 只看该作者
感谢分享,已经下载了~~
回复

使用道具 举报

8#
ID:565614 发表于 2019-6-18 13:10 | 只看该作者
没有积分能发一份给我吗/?新手学习中
回复

使用道具 举报

9#
ID:350791 发表于 2019-8-27 09:54 | 只看该作者
正在学习TCP协议,内容很好
回复

使用道具 举报

10#
ID:609989 发表于 2019-9-10 17:00 | 只看该作者
666谢谢啊
回复

使用道具 举报

11#
ID:625667 发表于 2019-10-24 17:20 | 只看该作者
楼主好人,谢谢分享
回复

使用道具 举报

12#
ID:625667 发表于 2019-10-24 17:21 | 只看该作者
不过话说回来了,C#社区开源确实跟Java没法比,找个稍微有用的就是买,GitHub也没有,哎
回复

使用道具 举报

13#
ID:384552 发表于 2019-10-31 15:59 | 只看该作者
太厉害的,谢谢
回复

使用道具 举报

14#
ID:663815 发表于 2019-12-14 15:44 | 只看该作者
厉害,找了很久!!
回复

使用道具 举报

15#
ID:544352 发表于 2020-1-4 13:50 | 只看该作者
源码规范合理,该有的都有了
回复

使用道具 举报

16#
ID:711047 发表于 2020-3-18 17:51 | 只看该作者
这个太棒了,谢谢楼主
回复

使用道具 举报

17#
ID:967451 发表于 2021-9-22 10:46 | 只看该作者
这个太棒了,谢谢楼主
回复

使用道具 举报

18#
ID:1003226 发表于 2022-2-23 12:26 | 只看该作者
CDSN下载都是要积分,这里好多了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表