alobiedy Ответов: 2

Как получить данные от RFID TCP/ip reader C# или VB.NET


я пытаюсь считывать данные с RFID-считывателя с помощью C# или VB.net

мой компьютер как сервер с ip 192.168.1.12 порт 9999

IP считывателя 192.168.1.99

https://preview.ibb.co/hi3gvf/555.jpg

Что я уже пробовал:

tcpLsn= new TcpListener(8002);
tcpLsn.Start();
Thread tcpThd = new Thread(new ThreadStart(WaitingForClient));
threadHolder.Add(connectId, tcpThd);
tcpThd.Start() ;
stpanel.Text = "Listen at: " + tcpLsn.LocalEndpoint.ToString();
menuStop.Checked=false;
MenuStartThread.Checked=true

Mehdi Gholam

Обратитесь к документации по устройству.

2 Ответов

Рейтинг:
14

Jason Gleim

Немного вещей... Программирование сокетов за пределами тривиальных примеров может привести к путанице, поэтому вот что вам нужно знать.

1) Ваш RFID-считыватель должен открыть соединение с сервером на определенном порту. Таким образом, ваш читатель должен быть запрограммирован на отправку сообщений на 192.168.1.12 через порт 9999. В вашем фрагменте кода вы прослушиваете порт 8002. Это одна из причин, по которой вы не получите никаких связей.

2) Если вы находитесь на сервере с несколькими сетевыми картами, вам нужно убедиться, что вы привязываете прослушиватель к правильному. Вы можете использовать Dns.GetHostEntry(Dns.GetHostName())
чтобы получить ваш IPHostEntry, который будет заполнен интерфейсами сервера в элементе AddressList.

The next thing you need to know is to understand the sequence of things when a connection is established. When you create a socket and call Accept or BeingAccept, the socket will wait for a connection from a client. When your reader connects, the socket either returns a new socket or will hit the callback method you provided where you get the new socket with EndAccept. The new socket is the CONNECTED socket for your client and you must call Receive or BeginReceive on the new socket. In the meantime, your original listening socket can go back to listening for a new connection. You can have up to x number of simultaneous connections based on the value you pass to the Listen method on the original socket.

Возвращаясь к новому сокету, подключенному к клиенту, вы либо получаете, либо начинаете получать данные из этого сокета. Вы указываете буфер при вызове этого метода, и когда он возвращается (или попадает в обратный вызов), вы получаете количество полученных байтов. Вы должны получить эти данные, а затем повторить процесс до тех пор, пока не получите все данные и не захотите закрыть соединение.

Последнее предостережение заключается в том, что закрытие сокета приводит к исключению. Это самая глупая вещь, но именно так она работает. Вы также должны закрыть сокеты по порядку, иначе вы рискуете потерять ссылку на подключенный сокет и тем самым утечка памяти до тех пор, пока приложение не закроется.

Я предлагаю вам, если вы не хотите, чтобы пользовательский интерфейс блокировался на вас, выполнить прослушивание рабочего потока. Я поместил свой класс В класс listener, чтобы открыть несколько портов для прослушивания нескольких устройств, создающих прослушиватели с фабрики. В моем коде ниже IPAddress и LIsteningPort являются свойствами класса. Я использую асинхронные методы в сокете, потому что хочу, чтобы пользовательский интерфейс мог закрыть прослушиватель или завершить работу упорядоченным образом. Если бы я использовал методы синхронизации, рабочий поток заблокировался бы, и я застрял бы, убивая поток нелюбезным способом.

Вот три важных метода::

private void _worker_DoWork(object sender, DoWorkEventArgs e)
{
    /* WHAT WE ARE DOING:
     * To begin, make sure we have valid parameters.
     * Check to make sure there isn't already a listener on the same IP/Port
     * Create the socket.
     * Bind to the socket.
     * Wait for a connection then do nothing until the connection closes or the thread is shut down.
     */

    BackgroundWorker worker = sender as BackgroundWorker;

    // Parameter checking
    if (IPAddress == null) throw new ArgumentNullException("IP Address");
    if (ListeningPort == 0) throw new ArgumentException("Listening Port");

    // Create an endpoint from the ip address and port
    IPEndPoint localEndPoint = new IPEndPoint(IPAddress, ListeningPort);
    // Create a TCP/IP socket if needed (might be re-used)
    _listeningSocket = new Socket(IPAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

    // Try to bind the socket...
    try
    {
        if (!_listeningSocket.IsBound)
            _listeningSocket.Bind(localEndPoint);
        _listeningSocket.Listen(1);

        // Clear the stop flag
        stopListener.Reset();

        _socketState = new SocketStateObject() { RootSocket = _listeningSocket, worker = worker };

        worker.ReportProgress(10);  // Report that we are running
        while (worker.CancellationPending == false)
        {
            if (!waitingForClient.WaitOne(0) && _socketState.ConnectedSocket == null)
            {
                // Start an async socket listening for connections...
                _listeningSocket.BeginAccept(new AsyncCallback(AcceptSocketCallback), _socketState);
                waitingForClient.Set();
            }
            stopListener.WaitOne(250);
        }

        // User wants to shut down...
        if (_socketState.ConnectedSocket != null)
        {
            if(_socketState.ConnectedSocket.Connected)
            {
                _socketState.ConnectedSocket.Shutdown(SocketShutdown.Both);
            }
            _socketState.ConnectedSocket.Close();
            _socketState.ConnectedSocket.Dispose();

            // Now close the main listening socket
            _listeningSocket.Close();
            _listeningSocket.Dispose();
        }
        if (waitingForClient.WaitOne(0))
        {
            // If we are waiting for a connection then just end the accept and close the socket.
            _listeningSocket.Close();
            _listeningSocket.Dispose();
        }

        RaisePropertyChanged("IsConnected");
        RaisePropertyChanged("IsListening");

        // Signal that we are stopped
        stopListener.Set();
    }
    catch (ObjectDisposedException ode)
    {
        // Nothing really to do. This just means the socket was closed.
    }
    catch (SocketException se)
    {
        ListenerErrorMsg = $"Unable to open the socket.";
        ListenerErrorCode = (int)se.SocketErrorCode;
        ListenerException = se;
        worker.ReportProgress(0, new ListenerErrorEventArgs(ListenerErrorMsg, ListenerErrorCode, ListenerException));
    }
    catch (SecurityException sec)
    {
        ListenerErrorMsg = $"Insufficient security to open the socket.";
        ListenerErrorCode = -2;
        ListenerException = sec;
        worker.ReportProgress(0, new ListenerErrorEventArgs(ListenerErrorMsg, ListenerErrorCode, ListenerException));
    }
    catch (Exception ex)
    {
        ListenerErrorMsg = $"Could not bind to the specified socket for an unknown reason.";
        ListenerErrorCode = -2;
        ListenerException = ex;
        worker.ReportProgress(0, new ListenerErrorEventArgs(ListenerErrorMsg, ListenerErrorCode, ListenerException));
    }
}

// Accepts a connection on the listening socket
private void AcceptSocketCallback(IAsyncResult ar)
{
    SocketStateObject state = ar.AsyncState as SocketStateObject;
    // Get the socket that handles the client request.
    try
    {
        Socket listener = state.RootSocket;
        Socket handler = listener.EndAccept(ar);

        // Create the state object.
        state.ConnectedSocket = handler;
        handler.BeginReceive(state.buffer, 0, SocketStateObject.BufferSize, 0,
        new AsyncCallback(ReadSocketCallback), state);

        RaisePropertyChanged("IsConnected");
        // Signal the main thread to continue.
        waitingForClient.Reset();
    }
    catch (ObjectDisposedException)
    {
        // Just eat the exception because it means the socket is closed.
        state.RootSocket = null;
        RaisePropertyChanged("IsConnected");
    }
}

private void ReadSocketCallback(IAsyncResult ar)
{
    string content = string.Empty;
    StringBuilder sb = new StringBuilder();

    // Retrieve the state object and the handler socket
    // from the asynchronous state object.
    SocketStateObject state = (SocketStateObject)ar.AsyncState;
    Socket handler = state.ConnectedSocket;

    // Clear the string builder
    sb.Clear();

    // Read data from the client socket.
    try
    {
        int bytesRead = handler.EndReceive(ar);

        if (bytesRead > 0)
        {
            // Got data back in the message
            sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
            // Read the content of the string builder into a string
            content = sb.ToString();
            // Check to see if the content string has null bytes at the end (arrive as \0). The PLC pads the string with those. :-/
            int zeroBytePos = content.IndexOf(Convert.ToChar(0));
            if (zeroBytePos > 0)
                content = content.Substring(0, zeroBytePos);
            // Display it on the console.
            Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
                content.Length, content);
            // Set the last message received
            LastMessage = content;
            state.worker.ReportProgress(50, content);

            // Re-trigger on Begin Receive in case there is more.
            handler.BeginReceive(state.buffer, 0, SocketStateObject.BufferSize, 0,
            new AsyncCallback(ReadSocketCallback), state);
        }
    }
    catch (ObjectDisposedException)
    {
        // Just eat the exception because it means the socket is closed.
        state.ConnectedSocket = null;
        RaisePropertyChanged("IsConnected");
    }
    catch (SocketException)
    {
        // Probably a closed connection on the far end. We need to go back into accept mode.
        if (state.ConnectedSocket.Connected)
        {
            state.ConnectedSocket.Shutdown(SocketShutdown.Both);
        }
        state.ConnectedSocket.Close();
        state.ConnectedSocket.Dispose();
        state.ConnectedSocket = null;
        RaisePropertyChanged("IsConnected");
    }

}

// State object for reading client data asynchronously
internal class SocketStateObject
{
    private readonly Object thisLock = new Object();
    private Socket _rootSocket = null;
    private Socket _connectedSocket = null;


    // Parent socket. This is the one that accepts connections
    internal Socket RootSocket
    {
      


Dave Kreskowiak

Ницца. Работа "сверх и сверх".

alobiedy

Привет Permalink и спасибо за отличное объяснение
у меня есть этот читатель
https://imgur.com/emfs9MH
подключенный к моему компьютеру с помощью RJ45 мой IP ПК это ip сервера 192.168.1.12 порт сервера 9999 ip считывателя 192.168.1.99 и это приложение параметров для считывателя
https://imgur.com/B0Kmezn
когда я использую тестовую программу chainese для читателя, это то, что я получаю
https://imgur.com/g3FTN55
с каждой карты, которую я сканирую
и вот эти документы я нашел для этого читателя
https://drive.google.com/file/d/1b9NgiGUPxZfwfTxT610ygCyZaudAjwLx/view?usp=sharing

https://drive.google.com/file/d/1ibHeIJZxOdpFTUag4__WWxTB9FVwq_Fk/view?usp=sharing

я хочу получить эти коды от читателя я пытался контролировать порт сокет 9999 и пытался слушать из порта но безуспешно

cardid=DC9279&mjihao=1&cjihao=HW25E5ED&status=11&time=1420079413/qa/mcardsea.aspx?cardid=DC9279&mjihao=1&cjihao=HW25E5ED&status=11&time=1420079413

большое спасибо за вашу помощь


Jason Gleim

Я предлагаю вам скачать и установить "отправитель пакетов" из packetsender.com. Он может действовать как отправитель, так и слушатель с гибкой настройкой для UDP и TCP на любом порту, который вы хотите назначить. Используйте его, чтобы точно увидеть, что ваш читатель посылает вам, а затем вы можете использовать мой код оттуда.

Удачи вам!
Джейсон

Рейтинг:
1

Ebenezar John Paul

Я считаю, что ключ к вашему требованию лежит в обработчиках потока. Для этого сценария NetworkStream был бы более подходящим вариантом. Но вы можете решить, исходя из ваших потребностей.

Вот элегантный образец от доттуториалы

Хостинг Данных (Сервер):

static string ReadData(NetworkStream network)
{
    string Output = string.Empty;
    byte[] bReads = new byte[1024];
    int ReadAmount = 0;

    while (network.DataAvailable)
    {
        ReadAmount = network.Read(bReads, 0, bReads.Length);
        Output += string.Format("{0}", Encoding.UTF8.GetString(
            bReads, 0, ReadAmount));
    }
    return Output;
}

static void WriteData(NetworkStream stream, string cmd)
{
    stream.Write(Encoding.UTF8.GetBytes(cmd), 0,
    Encoding.UTF8.GetBytes(cmd).Length);
}

static void Main(string[] args)
{
    List<TcpClient> clients = new List<TcpClient>();
    TcpListener listener = new TcpListener(new IPEndPoint(IPAddress.Any, 1337));
    //listener.ExclusiveAddressUse = true; // One client only?
    listener.Start();
    Console.WriteLine("Server booted");

    Func<TcpClient, bool> SendMessage = (TcpClient client) => { 
        WriteData(client.GetStream(), "Responeded to client");
        return true;
    };

    while (true)
    {
        if (listener.Pending()) {
            clients.Add(listener.AcceptTcpClient());
        }

        foreach (TcpClient client in clients) {
            if (ReadData(client.GetStream()) != string.Empty) {
                Console.WriteLine("Request from client");
                SendMessage(client);
             }
        }
    }
}


Теперь клиент будет использовать следующий метод для отправки запроса:
static string ReadData(NetworkStream network)
{
    string Output = string.Empty;
    byte[] bReads = new byte[1024];
    int ReadAmount = 0;

    while (network.DataAvailable)
    {
        ReadAmount = network.Read(bReads, 0, bReads.Length);

        Output += string.Format("{0}", Encoding.UTF8.GetString(
                bReads, 0, ReadAmount));
    }
    return Output;
}

static void WriteData(NetworkStream stream, string cmd)
{
    stream.Write(Encoding.UTF8.GetBytes(cmd), 0,
                Encoding.UTF8.GetBytes(cmd).Length);
}

static void Main(string[] args)
{
    TcpClient client = new TcpClient();
    client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1337));
    while (!client.Connected) { } // Wait for connection

    WriteData(client.GetStream(), "Send to server");
    while (true) {
        NetworkStream strm = client.GetStream();
        if (ReadData(strm) != string.Empty) {
            Console.WriteLine("Recieved data from server.");
        }
    }
}


Я надеюсь, что это каким-то образом поможет вам достичь своей цели. Здесь есть ссылка на источник, не стесняйтесь дать ей большой палец вверх для автора.