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)
{
BackgroundWorker worker = sender as BackgroundWorker;
if (IPAddress == null) throw new ArgumentNullException("IP Address");
if (ListeningPort == 0) throw new ArgumentException("Listening Port");
IPEndPoint localEndPoint = new IPEndPoint(IPAddress, ListeningPort);
_listeningSocket = new Socket(IPAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
if (!_listeningSocket.IsBound)
_listeningSocket.Bind(localEndPoint);
_listeningSocket.Listen(1);
stopListener.Reset();
_socketState = new SocketStateObject() { RootSocket = _listeningSocket, worker = worker };
worker.ReportProgress(10);
while (worker.CancellationPending == false)
{
if (!waitingForClient.WaitOne(0) && _socketState.ConnectedSocket == null)
{
_listeningSocket.BeginAccept(new AsyncCallback(AcceptSocketCallback), _socketState);
waitingForClient.Set();
}
stopListener.WaitOne(250);
}
if (_socketState.ConnectedSocket != null)
{
if(_socketState.ConnectedSocket.Connected)
{
_socketState.ConnectedSocket.Shutdown(SocketShutdown.Both);
}
_socketState.ConnectedSocket.Close();
_socketState.ConnectedSocket.Dispose();
_listeningSocket.Close();
_listeningSocket.Dispose();
}
if (waitingForClient.WaitOne(0))
{
_listeningSocket.Close();
_listeningSocket.Dispose();
}
RaisePropertyChanged("IsConnected");
RaisePropertyChanged("IsListening");
stopListener.Set();
}
catch (ObjectDisposedException ode)
{
}
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));
}
}
private void AcceptSocketCallback(IAsyncResult ar)
{
SocketStateObject state = ar.AsyncState as SocketStateObject;
try
{
Socket listener = state.RootSocket;
Socket handler = listener.EndAccept(ar);
state.ConnectedSocket = handler;
handler.BeginReceive(state.buffer, 0, SocketStateObject.BufferSize, 0,
new AsyncCallback(ReadSocketCallback), state);
RaisePropertyChanged("IsConnected");
waitingForClient.Reset();
}
catch (ObjectDisposedException)
{
state.RootSocket = null;
RaisePropertyChanged("IsConnected");
}
}
private void ReadSocketCallback(IAsyncResult ar)
{
string content = string.Empty;
StringBuilder sb = new StringBuilder();
SocketStateObject state = (SocketStateObject)ar.AsyncState;
Socket handler = state.ConnectedSocket;
sb.Clear();
try
{
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
content = sb.ToString();
int zeroBytePos = content.IndexOf(Convert.ToChar(0));
if (zeroBytePos > 0)
content = content.Substring(0, zeroBytePos);
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
content.Length, content);
LastMessage = content;
state.worker.ReportProgress(50, content);
handler.BeginReceive(state.buffer, 0, SocketStateObject.BufferSize, 0,
new AsyncCallback(ReadSocketCallback), state);
}
}
catch (ObjectDisposedException)
{
state.ConnectedSocket = null;
RaisePropertyChanged("IsConnected");
}
catch (SocketException)
{
if (state.ConnectedSocket.Connected)
{
state.ConnectedSocket.Shutdown(SocketShutdown.Both);
}
state.ConnectedSocket.Close();
state.ConnectedSocket.Dispose();
state.ConnectedSocket = null;
RaisePropertyChanged("IsConnected");
}
}
internal class SocketStateObject
{
private readonly Object thisLock = new Object();
private Socket _rootSocket = null;
private Socket _connectedSocket = null;
internal Socket RootSocket
{
get
{
return _rootSocket;
}
set
{
lock (thisLock)
{
if (_rootSocket != value)
_rootSocket = value;
}
}
}
internal Socket ConnectedSocket
{
get
{
return _connectedSocket;
}
set
{
lock (thisLock)
{
if (_connectedSocket != value)
_connectedSocket = value;
}
}
}
internal const int BufferSize = 1024;
internal byte[] buffer = new byte[BufferSize];
internal BackgroundWorker worker = null;
}