简体   繁体   English

使用c#从TCP IP硬件设备接收数据块

[英]Receiving blocks of data from a TCP IP hardware device using c#

I have a barcode scanner hardware device that continually scans barcodes passing passing by and sends the data through it's tcpip port. 我有一个条形码扫描仪硬件设备,它可以连续扫描经过的条形码,并通过其tcpip端口发送数据。 The scanner is installed on a production line and reads all passing barcodes for verification purposes. 扫描仪安装在生产线上,并读取所有通过的条形码以进行验证。 There isn't any information sent to the barcode scanner other than what might be sent through the NetworkStream class upon connection. 除了连接时可能通过NetworkStream类发送的信息外,没有其他任何信息发送至条形码扫描仪。 I implemented a very simple interface to verify connectivity and receipt of the expected data being sent by the device. 我实现了一个非常简单的界面,以验证连接性和设备发送的预期数据的接收情况。 Obviously the problem with this code is it only iterates a certain number of times. 显然,此代码的问题在于它仅迭代一定次数。 Regardless of the looping choice, I need an app that receives data and continues to receive data until my code chooses to stop close the connection and stop receipt of data. 无论采用哪种循环方式,我都需要一个可以接收数据并继续接收数据的应用程序,直到我的代码选择停止关闭连接并停止接收数据为止。 It has to always be watching the port for incoming data from the device's tcp ip server. 它必须始终在监视端口中是否有来自设备的tcp ip服务器的传入数据。

public void readData()
    {
        int n = 1;

            Byte[] data;
            Int32 port = 51236;
            TcpClient client = new TcpClient("192.168.0.70", port);
            NetworkStream stream = client.GetStream();
            String responseData = String.Empty;
            try
            {
                while (n < 50)
                {
                data = new Byte[256];  //arbitrary length for now

                // String to store the response ASCII representation.

                // Read the first batch of the TcpServer response bytes.
                Int32 bytes = stream.Read(data, 0, data.Length);
                responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
                m_upcCode = responseData;
                n++;
                }
            }
            catch (ArgumentNullException ArgEx)
            {
                m_upcCode = "ArgumentNullException: {0}" + ArgEx.Message.ToString();
            }
            catch (SocketException exSocket)
            {
                m_upcCode = "SocketException: {0}" + exSocket.Message.ToString();
            }
    }

I've been looking through numerous posts regarding establishing a connection to a tcp ip server and receiving data from the server. 我一直在浏览有关建立与tcp ip服务器的连接并从服务器接收数据的大量文章。 The post I found with the most promise might be Can a TCP c# client receive and send continuously/consecutively without sleep? 我发现最有前途的帖子可能是TCP c#客户端可以连续/连续地接收和发送不睡觉吗? . I'm just having an issue understanding how to implement the design. 我只是在了解如何实施设计方面遇到问题。 I would be happy just to see the code from that post simply called and implemented on a form and display data in a text box. 我很高兴看到帖子中的代码被简单地调用并在窗体上实现,并在文本框中显示数据。 The data being received is always a fixed length of 12 digits of a bar code and a . 所接收的数据始终是条形码和a的12位固定长度。 The data doesn't stop unless the conveyor belt stops. 除非传送带停止,否则数据不会停止。 But we don't want the connection to close just because of a line pause. 但是我们不希望仅由于行暂停而关闭连接。 There was also a post at C# TCP Client listening for data specifically trying to address reading barcodes but didn't get much of a response. C#TCP Client上也有一个帖子,专门监听试图读取条形码的数据,但是没有得到太多响应。

Take out the counter completely. 完全取出柜台。 When you do a read and there are zero bytes returned, put the thread to sleep momentarily, and loop. 当您进行读取并返回零字节时,使线程暂时进入睡眠状态并循环。

public void readData()
{
    Byte[] data;
    Int32 port = 51236;
    TcpClient client = new TcpClient("192.168.0.70", port);
    NetworkStream stream = client.GetStream();
    String responseData = String.Empty;
    try
    {
        while (true)
        {
            data = new Byte[256];  //arbitrary length for now

            // String to store the response ASCII representation.

            // Read the first batch of the TcpServer response bytes.
            Int32 bytes = stream.Read(data, 0, data.Length);
            if (bytes == 0){
                System.Threading.Thread.Sleep(1000);
            }
            else {
                responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
                m_upcCode = responseData;
            }
        }
    }
    catch (ArgumentNullException ArgEx)
    {
        m_upcCode = "ArgumentNullException: {0}" + ArgEx.Message.ToString();
    }
    catch (SocketException exSocket)
    {
        m_upcCode = "SocketException: {0}" + exSocket.Message.ToString();
    }
}

Maybe this code can help you. 也许这段代码可以为您提供帮助。 It's a TCP server i wrote for a connector (protocol conversion) application. 这是我为连接器(协议转换)应用程序编写的TCP服务器。 It can only handle one connection from one client. 它只能处理来自一个客户端的一个连接。 It run's a separate thread and can be controlled trough some public methods. 它是一个单独的线程,可以通过某些公共方法进行控制。 It raises event's to communicate with other code. 它引发事件以与其他代码进行通信。 You might need to alter some code (for example the logging part). 您可能需要更改一些代码(例如,日志记录部分)。 I hope it helps you. 希望对您有帮助。

public class TCPServer : ITCPServer
{
    private readonly IPEndPoint _ipEndPoint;
    private TcpListener _tcpListener;
    private TcpClient _tcpClient;
    private bool _runServer;
    private bool _connectToClient;
    private NetworkStream _networkStream;
    private volatile bool _isRunning;

    public TCPServer(IPEndPoint ipEndpoint)
    {
        _ipEndPoint = ipEndpoint;
    }

    #region Properties

    public bool IsRunning
    {
        get { return _isRunning; }
    }

    #endregion

    #region Events

    public event Action<byte[]> OnMessageReceived;
    public event Action<string> OnConnectionOpened;
    public event Action<string> OnConnectionClosed;
    public event Action<LogLevel, string> OnLogMessage;

    #endregion

    #region Public Methods

    public void Start()
    {
        _tcpListener = new TcpListener(_ipEndPoint);
        _runServer = true;
        _tcpListener.Start();

        var thread = new Thread(RunServerEngine);
        thread.Name = "TcpServer";
        thread.Start();

        while (!_isRunning)
        {
        }

        var localEndpoint = (IPEndPoint)_tcpListener.LocalEndpoint;
        RaiseOnLogMessage(LogLevel.Info, String.Format("Server started listening at ip address {0} on port {1}", localEndpoint.Address, localEndpoint.Port));
    }

    public void Stop()
    {
        _connectToClient = false;
        _runServer = false;
    }

    public void SendMessage(byte[] message)
    {
        _networkStream.Write(message, 0, message.Length);
        _networkStream.Flush();
    }

    public void DisconnectClient()
    {
        _connectToClient = false;
    }

    #endregion

    #region Private Methods

    private void RunServerEngine(Object obj)
    {
        try
        {
            _isRunning = true;

            while (_runServer)
            {
                Thread.Sleep(250);
                if (_tcpListener.Pending())
                {
                    using (_tcpClient = _tcpListener.AcceptTcpClient())
                    {
                        var socketForClient = _tcpClient.Client;
                        _networkStream = new NetworkStream(socketForClient);
                        RaiseOnConnectionOpened((IPEndPoint)_tcpClient.Client.RemoteEndPoint);
                        _connectToClient = true;

                        while (_connectToClient)
                        {
                            if (CheckClientConnection() == false)
                            {
                                _connectToClient = false;
                                break;
                            }

                            if (_networkStream.DataAvailable)
                            {
                                var bytes = new Byte[1024];
                                _networkStream.Read(bytes, 0, 1024);
                                bytes = bytes.TakeWhile(b => b > 0).ToArray();
                                RaiseOnMessageReceived(bytes);
                            }

                            Thread.Sleep(100);
                        }
                    }
                    RaiseOnConnectionClosed();
                }
            }

            RaiseOnLogMessage(LogLevel.Info, "Stopping TCP Server");
            _tcpListener.Stop();
            _isRunning = false;
            RaiseOnLogMessage(LogLevel.Info, "TCP Server stopped");
        }
        catch (Exception ex)
        {
            RaiseOnLogMessage(LogLevel.Error, String.Format("Fatal error in TCP Server, {0}", ex.ToString()));
            throw;
        }
    }


    private bool CheckClientConnection()
    {
        var connected = true;

        try
        {
            var pollResult = _tcpClient.Client.Poll(1, SelectMode.SelectRead);
            var dataAvailable = _tcpClient.Client.Available;
            connected = !(pollResult && _tcpClient.Client.Available == 0);

            if (!connected)
            {
                RaiseOnLogMessage(LogLevel.Info, "Detected disconnection from client");
                RaiseOnLogMessage(LogLevel.Info, String.Format("TCPServer.CheckClientConnection - connected: {0}, pollResult: {1}, dataAvailable: {2}", connected, pollResult, dataAvailable));
            }
        }
        catch (SocketException ex)
        {
            RaiseOnLogMessage(LogLevel.Info, String.Format("Exception occurred in TCPServer.CheckClientConnection. Ex: {0}", ex.ToString()));
            connected = false;
        }

        return connected;
    }

    private void RaiseOnMessageReceived(byte[] message)
    {
        if (OnMessageReceived != null)
        {
            try
            {
                OnMessageReceived(message);
            }
            catch (Exception ex)
            {
                RaiseOnLogMessage(LogLevel.Warning, ex.Message);
            }
        }
    }

    private void RaiseOnConnectionOpened(IPEndPoint remoteEndpoint)
    {
        if (OnConnectionOpened != null)
        {
            var msg = String.Format("Connected to client with ip address: {0}, port: {1}", remoteEndpoint.Address, remoteEndpoint.Port);
            OnConnectionOpened(msg);
        }
    }

    private void RaiseOnConnectionClosed()
    {
        if (OnConnectionClosed != null)
            OnConnectionClosed("Disconnected from client");
    }

    private void RaiseOnLogMessage(LogLevel level, string message)
    {
        if (OnLogMessage != null)
            OnLogMessage(level, message);
    }

    #endregion
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM