Could not receive data from serial port for some time.

Django

New member
Joined
Nov 24, 2019
Messages
1
Programming Experience
1-3
I use VS2017 , .net 4.7 in windows 7. I have written a C# program to polling data from a serial port. But I could not get the data input from the serial port some time .
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 ListenClient()
        {
            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 ListenClientConnect()
        {
            
             while (true)
                {
                    this.clientSocket = socket.Accept();
                    this.clientSocket_2 = socket_2.Accept();
                    this.clientSocket_3 = socket_3.Accept();
                    this.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 = this.button7.Text;
                this.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 = this.button1.Text;
                this.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;
            }


        }
    }
}
The serial port receive" start "from outside and return " INITOK".

The problem is sometimes after run for some time , after sending " start " to this program, the " INITOK", could not be returned. Seems like sometimes polling the serial port could not work well for my program.
 
Last edited by a moderator:
insertcode.png
 
The likelihood of your getting any help based on a vague description and a huge wad of code is very small. You need to make a better effort to do what you can for yourself first. You should start by creating a simple test project with as little code as possible. And see if you can communicate as expected. If not, show us just that minimal code example and provide a detailed description of what you expect and what you see. If it does work, you can then start building the code up bit by bit until it breaks. You then know what what you did last is where the issue is, so you can investigate it. If you can't find the issue, you can then ask us but provide far more relevant information based on your own testing. Every line of irrelevant code you post makes it harder and more time-consuming for us to identify where the problem might be, never mind what's causing it.
 
That is an awful chunk of code to dump into a topic and expect someone to read though. At a glance however;
CheckForIllegalCrossThreadCalls = false;
That makes for bad programming practices. Since you are dealing with sockets, and the direction you are going with this, you have no way for sure to know what your code is doing on different threads and whether or not you may be interleaving data.

You already have a port listening in void ListenClientConnect and then trying to receive on void ReceiveMessage(object Form1) again on a new thread.... no no no, this 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 :
Press ENTER to continue...
Socket connected to [fe80::edf3:2034:7db3:1506%2]:11000
Text received : This is a test<EOF>
Echoed test = This is a test<EOF>
Waiting for a connection...
But once you try accessing a socket/port created by another thread, you will get shot down for it :
Exception thrown: 'System.Net.Sockets.SocketException' in System.dll
System.Net.Sockets.SocketException (0x80004005): Only one usage of each socket address (protocol/network address/port) is normally permitted

I think you've breached many thread safety rules. I'm sorry, but I'd bin this and start over, and write it properly. The Socket Class (System.Net.Sockets) recommends you should use BeginSend and EndSend if threads will be using the same socket to transmit or receive data, and that includes BeginReceive and EndReceive respectively Socket.BeginReceive Method (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 legal threadsafe manner, you should be executing Asynchronously : Asynchronous Server Socket Example and checking for blocking calls etc. Your current code is not delegating across each thread to the objects being used from the methods that created them, and you should be, especially to see what your code is doing on those other threads. You need to design a model and restructure this to factor in these alterations. I would be quicker to rewrite this than to edit and fix it.

There is also redundant casts here and there along with unnecessary qualifications to this, which should be removed on line 192, and 213. Also note, you can only use one TCP port at a time and for that you may want to consider using UDP instead, but if you make that switch; you may also have to deal with adding additional verification of your received data due to UDP being known for dropping packets.
 
Back
Top Bottom