一段时间无法从串行端口接收数据。

Django的

新成员
已加入
2019年11月24日
留言内容
1
编程经验
1-3
我在Windows 7中使用VS2017,.net 4.7。我编写了一个C#程序来从串行端口轮询数据。但是我有时无法从串行端口获取数据输入。
C#:
using System;
using System.Net;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Net.Sockets;
using System.Web;
using System.IO.Ports;
using System.Text.RegularExpressions;

namespace Socket_server_gangprogrammer
{
    public partial class Form1 : Form
    {
        public Socket clientSocket = null;
        public Socket clientSocket_2 = null;
        public Socket clientSocket_3 = null;
        public Socket clientSocket_4 = null;
        public static Socket myClientSocket = null;
        public static Socket myClientSocket_2 = null;
        public static Socket myClientSocket_3 = null;
        public static Socket myClientSocket_4 = null;
        static Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        static Socket socket_2 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        static Socket socket_3 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        static Socket socket_4 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private static byte[] result = new byte[1024];
        private static byte[] result_2 = new byte[1024];
        private static byte[] result_3 = new byte[1024];
        private static byte[] result_4 = new byte[1024];
        string result_str = null;
        string result_str_2 = null;
        string result_str_3 = null;
        string result_str_4 = null;
        string[] buf_str = new String[20];

        public Form1()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
   
            comboBox4.Items.Add("9600");
  
            textBox8.AppendText("8");
            textBox10.AppendText("None");
            textBox12.AppendText("one");


            try
            {
                //添加串口项目
                foreach (string s in SerialPort.GetPortNames())
                {//获取有多少个COM口              
                    comboBox3.Items.Add(s);
     
                }

                //串口设置默认选择项
                comboBox3.SelectedIndex = 1;
                comboBox4.SelectedIndex = 0;
 
            }
            catch (Exception ex)
            {               
                textBox2.AppendText(ex.ToString());
            }
        }
        public void SocketServie()
        {
            //服务端已启动
            string host = "127.0.0.1";//IP地址
            int port = 8021;//端口
            int port_2 = 8022;
            int port_3 = 8023;
            int port_4 = 8024;
            socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);     //port reuse
            socket_2.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            socket_3.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            socket_4.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            socket.Bind(new IPEndPoint(IPAddress.Parse(host), port));
            socket_2.Bind(new IPEndPoint(IPAddress.Parse(host), port_2));
            socket_3.Bind(new IPEndPoint(IPAddress.Parse(host), port_3));
            socket_4.Bind(new IPEndPoint(IPAddress.Parse(host), port_4));

            socket.Listen(100);//设定最多100个排队连接请求
            socket_2.Listen(100);
            socket_3.Listen(100);
            socket_4.Listen(100);
            Thread SocketThread = new Thread(this.ListenClientConnect);//通过多线程监听客户端连接 
            SocketThread.IsBackground = true;
            SocketThread.Start();
        }

        private void  清单 enClient()
        {
            try
            {
                DateTime now = DateTime.Now;
                //int nb = serialPort1.BytesToRead;
                int nb = 0;
                while (true)
                {
                    nb = serialPort1.BytesToRead;
                    if (nb > 0)
                    {
                        byte[] buffer = new byte[nb];
                        serialPort1.Read(buffer, 0, nb);

                        if (Encoding.UTF8.GetString(buffer).Contains("START"))
                        {                           
                            textBox2.AppendText(now.ToString("F") +  Encoding.UTF8.GetString(buffer) + "\r\n");
                           
                            serialPort1.WriteLine("<<INITIALOK>>\r");
                        }

                        if (System.Text.Encoding.UTF8.GetString(buffer).Contains("NEXT"))
                        {
                            textBox2.AppendText(now.ToString("F")  +  Encoding.UTF8.GetString(buffer) + "\r\n");                     
                     

                              
                            string sendMessage = "start burning " + DateTime.Now;
                            try
                            {
                                clientSocket.Send(Encoding.ASCII.GetBytes(sendMessage));
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex);
                            }
                            try
                            {
                                clientSocket_2.Send(Encoding.ASCII.GetBytes(sendMessage));
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex);
                            }
                            try
                            {
                                clientSocket_3.Send(Encoding.ASCII.GetBytes(sendMessage));
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex);
                            }
                            try
                            {
                                clientSocket_4.Send(Encoding.ASCII.GetBytes(sendMessage));
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex);
                            }
                            /*string sendMessage_2 = "waiting";
                            for (int i = 0; i < 15; i++)
                            {
                                clientSocket.Send(Encoding.ASCII.GetBytes(sendMessage_2));
                                clientSocket_2.Send(Encoding.ASCII.GetBytes(sendMessage_2));
                                clientSocket_3.Send(Encoding.ASCII.GetBytes(sendMessage_2));
                                clientSocket_4.Send(Encoding.ASCII.GetBytes(sendMessage_2));
                                //Thread.Sleep(1000);
                            }*/
                        }
                       
                    }
                }
            }
            catch (Exception ex)
            {
                textBox2.AppendText(ex.ToString());
            }
        }

        /// <summary> 
        /// 监听客户端连接 
        /// </summary> 
        private void  清单 enClientConnect()
        {
            
             while (true)
                {
                     这个 .clientSocket = socket.Accept();
                     这个 .clientSocket_2 = socket_2.Accept();
                     这个 .clientSocket_3 = socket_3.Accept();
                     这个 .clientSocket_4 = socket_4.Accept();

                    textBox2.AppendText("socket client accepted!\r\n");               

                    Thread receiveThread = new Thread(new ParameterizedThreadStart(ReceiveMessage));
                    receiveThread.IsBackground = true;
                    receiveThread.Start(this);
                    Thread.Sleep(1000);
                }
        }

        /// <summary> 
        /// 接收消息 
        /// </summary> 
        /// <param name="clientSocket"></param> 
        //public void ReceiveMessage(object clientSocket, object Form1)
        public void ReceiveMessage(object Form1)
        {
            Socket myClientSocket = (Socket)clientSocket;
            Socket myClientSocket_2 = (Socket)clientSocket_2;
            Socket myClientSocket_3 = (Socket)clientSocket_3;
            Socket myClientSocket_4 = (Socket)clientSocket_4;
            while (true)
            {
                try
                {
                    if (result_str == null)
                    {
                        int receiveNumber = myClientSocket.Receive(result);      //通过clientSocket接收数据
                        //Console.WriteLine(receiveNumber);
                        result_str = Encoding.UTF8.GetString(result, 0, receiveNumber);
                        //Console.WriteLine(result_str);
                        //textBox2.AppendText("result_str: " + result_str + "  ");
                    }
                    else
                    {
                        textBox2.AppendText("***result_str: " + result_str + "  ");
                    }
                    if (result_str_2 == null)
                    {
                        int receiveNumber_2 = myClientSocket_2.Receive(result_2);
                        //Console.WriteLine(receiveNumber_2);
                        result_str_2 = Encoding.UTF8.GetString(result_2, 0, receiveNumber_2);
                        //Console.WriteLine(result_str_2);
                        //textBox2.AppendText("result_str_2: " + result_str_2 + "  ");
                    }
                    else
                    {
                        textBox2.AppendText("***result_str_2: " + result_str_2 + "  ");
                    }
                    if (result_str_3 == null)
                    {
                        int receiveNumber_3 = myClientSocket_3.Receive(result_3);
                       // Console.WriteLine(receiveNumber_3);
                        result_str_3 = Encoding.UTF8.GetString(result_3, 0, receiveNumber_3);
                        //Console.WriteLine(result_str_3);
                        //textBox2.AppendText("result_str_3: " + result_str_3 + "  ");
                    }
                    else
                    {
                        textBox2.AppendText("***result_str_3: " + result_str_3 + "  ");
                    }
                    if (result_str_4 == null)
                    {
                        int receiveNumber_4 = myClientSocket_4.Receive(result_4);
                        //Console.WriteLine(receiveNumber_4);
                        result_str_4 = Encoding.UTF8.GetString(result_4, 0, receiveNumber_4);
                        //Console.WriteLine(result_str_4);
                        //textBox2.AppendText("result_str_4: " + result_str_4 + "  ");
                    }
                    else
                    {
                        textBox2.AppendText("***result_str_4: " + result_str_4 + "  ");
                    }

                    if (result_str != null && result_str_2 != null && result_str_3 != null && result_str_4 != null)
                    {
                        serialPort1.WriteLine("<<" + result_str[0] + result_str[2] + result_str[4] + result_str[6] + result_str[8] + result_str[10] + result_str[12] + result_str[14] + result_str_2[0] + result_str_2[2] + result_str_2[4] + result_str_2[6] + result_str_2[8] + result_str_2[10] + result_str_2[12] + result_str_2[14]  + result_str_3[0] + result_str_3[2] + result_str_3[4] + result_str_3[6] + result_str_3[8] + result_str_3[10] + result_str_3[12] + result_str_3[14]  + result_str_4[0] + result_str_4[2] + result_str_4[4] + result_str_4[6] + result_str_4[8] + result_str_4[10] +  ">>" + "\r");
                        //Console.WriteLine("<<" + result_str[0] + result_str[2] + result_str[4] + result_str[6] + result_str[8] + result_str[10] + result_str[12] + result_str[14] + result_str_2[0] + result_str_2[2] + result_str_2[4] + result_str_2[6] + result_str_2[8] + result_str_2[10] + result_str_2[12] + result_str_2[14] + result_str_3[0] + result_str_3[2] + result_str_3[4] + result_str_3[6] + result_str_3[8] + result_str_3[10] + result_str_3[12] + result_str_3[14] + result_str_4[0] + result_str_4[2] + result_str_4[4] + result_str_4[6] + result_str_4[8] + result_str_4[10] + ">>" + "\r\n");
                        result_str = null;
                        result_str_2 = null;
                        result_str_3 = null;
                        result_str_4 = null;                       
                    }
                }
                catch (Exception ex)
                {
                    textBox2.AppendText("error!!!" + ex + "\r\n");
                    //myClientSocket.Shutdown(SocketShutdown.Both);//禁止发送和上传
                    //myClientSocket.Close();//关闭Socket并释放资源
                    break;
                }
            }     
        }
        private void button7_Click(object sender, EventArgs e)
        {

            try
            {
                string text =  这个 .button7.Text;
                 这个 .button7.Text = text == "connected" ? "disconnected" : "connected";

                if (serialPort1.IsOpen)
                {
                    serialPort1.Close();
                    serialPort1 = null;                   
                }
                else
                {
                    serialPort1.BaudRate = 9600;
                    serialPort1.PortName = comboBox3.Text;
                    serialPort1.DataBits = 8;
                    try
                    {
                        if (!serialPort1.IsOpen)
                        {
                            serialPort1.Open();//打开串口
                        }
                    }
                    catch (Exception e1)
                    {
                        textBox2.AppendText(e1.Message);
                    }
                }

            }

            catch (Exception e1)
            {
                textBox2.AppendText(e1.Message);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                string text =  这个 .button1.Text;
                 这个 .button1.Text = text == "started" ? "stop" : "started";

                textBox2.AppendText("--------started !!!--------\r\n");

                //Start Socket
                SocketServie();
           

                Thread WorkThread = new Thread(this.ListenClient);
                WorkThread.IsBackground = true;
                WorkThread.Start();
            }
            catch (Exception e2)
            {
                textBox2.AppendText(e2.Message);
            }
        }

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.Close();
                serialPort1 = null;
            }


        }
    }
}
串口接收" start "从外面回来" INITOK".

问题有时是在运行一段时间后,发送后" start "对于这个程序," INITOK",无法退回。似乎有时轮询串行端口无法对我的程序很好地工作。
 
由主持人最后编辑:

约翰·H

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
1,028
地点
挪威
编程经验
10+
insertcode.png
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,501
地点
悉尼,澳大利亚
编程经验
10+
根据模糊的描述和大量的代码,您获得帮助的可能性很小。您需要做出更大的努力,首先为自己做自己能做的事情。您应该首先创建一个包含尽可能少代码的简单测试项目。并查看您是否可以按预期进行交流。如果不是这样,请仅向我们显示该最少的代码示例,并详细说明您的期望和所见。如果确实有效,则可以逐步构建代码,直到代码破裂为止。然后,您知道您最后做的是问题所在,因此可以进行调查。如果找不到问题,则可以问我们,但是根据您自己的测试提供更多相关信息。您发布的每一行不相关的代码使我们更难,更耗时地确定问题所在,而不必担心是什么原因。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,925
地点
英国
编程经验
10+
那是一堆可怕的代码,可以转储到一个主题中,但是希望有人阅读。一目了然;
CheckForIllegalCrossThreadCalls = false;
这会导致不良的编程习惯。由于您正在处理套接字,以及处理此套接字的方向,因此您无法确定自己的代码在不同线程上正在做什么以及是否要交织数据。

You already have a port listening in void 清单 enClientConnect and then trying to receive on void ReceiveMessage(object Form1) again on a new thread.... no no no, 这个 is all wrong. And just to prove to myself that I was right, you cannot do that. I just took the Microsoft client server from their documentation and executed one of each client and server on the same ports but on different threads and it throws an exception as I expected. I will of course connect fine if I am connecting only once :
按ENTER继续...
套接字已连接到[fe80 :: edf3:2034:7db3:1506%2]:11000
收到的文字:这是一个测试<EOF>
回显测试=这是一个测试<EOF>
正在等待连接...
但是一旦您尝试访问由另一个线程创建的套接字/端口,您将被拒绝:
抛出异常:System.dll中的“ System.Net.Sockets.SocketException”
System.Net.Sockets.SocketException(0x80004005):每个套接字地址(协议/网络地址/端口)通常只允许使用一种

我认为您违反了许多线程安全规则。对不起,但是我将对此进行分类并重新开始,然后正确编写。的 套接字类(System.Net.Sockets) 如果线程将使用同一套接字来传输或接收数据,并且建议分别包含BeginReceive和EndReceive,则建议您使用BeginSend和EndSend Socket.BeginReceive方法(System.Net.Sockets).

If one thread is already listening, you can't just use another thread to receive on a port that was accessed and controlled by another thread despite using CheckForIllegalCrossThreadCalls which is really only effective for debugging, and is not intended for use in production code anyway. Nor will it help you to ignore accessing a socket/port created and in use on/by another thread. And even if you were using threadsafe code in a 法律 以线程安全的方式,您应该异步执行: 异步服务器套接字示例 您的当前代码并未将每个线程从创建它们的方法中委派给正在使用的对象,您应该这样做,尤其是要查看您的代码在其他线程上的作用。您需要设计一个模型并对其进行重组以考虑这些变更。我会比编辑和修复它更快地重写它。

到处都有多余的演员,以及不必要的资格 这个 ,应该在第192行和第213行中将其删除。还要注意,您一次只能使用一个TCP端口,为此,您可能要考虑改用UDP,但是如果您进行该切换,则可以使用UDP。由于已知UDP会丢弃数据包,因此您可能还需要对接收到的数据进行额外的验证。
 
最佳 底部