Click here to Skip to main content
14,334,249 members
Rate this:
Please Sign up or sign in to vote.
See more:
i am trying to read data from RFID reader using C# or VB.net

my PC as server with ip 192.168.1.12 Port 9999

reader IP 192.168.1.99

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

What I have tried:

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
Posted
Updated 22-Oct-18 4:13am
Comments
Mehdi Gholam 21-Oct-18 2:31am
   
Consult the documentation for the device.
Rate this:
Please Sign up or sign in to vote.

Solution 1

Few things... Socket programming beyond the trivial examples can be confusing so here is what you need to know.

1) Your RFID reader needs to open a connection to the server on a specific port. So you reader should be programmed to send messages to 192.168.1.12 on port 9999. In your code snippet, you are listening on port 8002. That is one reason you won'get get any connections.

2) If you are on a server with multiple network cards, you need to make sure you are binding the listener to the correct one. You can use Dns.GetHostEntry(Dns.GetHostName())
to get your IPHostEntry which will be populated with the server's interfaces in the AddressList member.

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.

Back to the new socket that is connected to the client, you either Receive or BeginReceive to get data from that socket. You specify the buffer when you call that method and when it returns (or hits the callback) you get the number of bytes received. You have to fetch that data then repeat the process until you get all the data and want to close the connection.

The last caveat is that closing a socket results in an exception. This is the dumbest thing but that is how it works. You also have to close sockets in order or you risk losing the reference to a connected socket and thereby leaking memory until you app closes.

I suggest that if you don't want the UI to lock up on you, that you do the listening on a worker thread. I put mine in a listener class so I can open multiple ports to listen for multiple devices creating listeners from a factory. In my code below, IPAddress and LIsteningPort are class properties. I use the async methods on the socket because I want to UI to be able to close the listener or shutdown in a orderly manner. If I used the sync methods, the worker thread would block and I would be stuck killing the thread in an ungraceful way.

Here are the three important methods:
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
    {
        get
        {
            return _rootSocket;
        }
        set
        {
            lock (thisLock)
            {
                if (_rootSocket != value)
                    _rootSocket = value;
            }
        }
    }
    // Connected socket is the one opened to a specific connection in response to EndAccept.
    internal Socket ConnectedSocket
    {
        get
        {
            return _connectedSocket;
        }
        set
        {
            lock (thisLock)
            {
                if (_connectedSocket != value)
                    _connectedSocket = value;
            }
        }
    }
    // Size of receive buffer.
    internal const int BufferSize = 1024;
    // Receive buffer.
    internal byte[] buffer = new byte[BufferSize];
    // background worker thread
    internal BackgroundWorker worker = null;
}
   
Comments
Dave Kreskowiak 22-Oct-18 11:53am
   
Nice. "Over and above" work.
alobiedy 22-Oct-18 19:53pm
   
Hi Permalink and Thanks for the great explanation
i have this reader
https://imgur.com/emfs9MH
connected to my pc with RJ45 my pc ip is the server ip 192.168.1.12 server port is 9999 the reader ip is 192.168.1.99 and this the parameters app for the reader
https://imgur.com/B0Kmezn
when i use the chainese test program for the reader that what i get
https://imgur.com/g3FTN55
from every card i scan
and this the documents i found for this reader
https://drive.google.com/file/d/1b9NgiGUPxZfwfTxT610ygCyZaudAjwLx/view?usp=sharing

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

i want to get this codes from reader i tried to monitor port socket 9999 and tried to listen from the port but no luck

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

thanks a lot for your help


Jason Gleim 23-Oct-18 8:04am
   
I suggest you download and install "Packet Sender" from packetsender.com. It can act as both a sender and listener with flexible setup for UDP and TCP on any port you wish to assign. Use it to see exactly what your reader is sending you then you can use my code from there.

Good luck!
Jason
Rate this:
Please Sign up or sign in to vote.

Solution 2

I believe the key to your requirement lies in the stream handlers. For this scenario, NetworkStream would be a better suitable option. But, you can decide based on your need.

Here is an elegant sample by dottutorials

Hosting Data (Server):
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);
             }
        }
    }
}


Now the client would then use the following method to send the request:
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.");
        }
    }
}


I hope it helps in some way to achieve your goal. Here is the link to the source, don't hesitate to give it a thumbs up for the author.
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month



CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100