[C#.NET][TCP Socket] 利用 Socket 同步方法 監聽 Alien Reader
Alien Reader 同時存在 主/被動 兩種模式,要設定主動模式得依手冊上的參數設定
以下是我的參數表
AutoMode = "On"
NotifyMode = "On"
TagStreamMode = "On"
IOStreamMode = "On"
//Auto
AutoWaitOutput = "-1"
AutoWorkOutput = "-1"
AutoTrueOutput = "-1"
AutoFalseOutput = "-1"
//Notify
NotifyAddress = "192.168.1.111"
NotifyTime = "5"
NotifyFormat = "Text"
NotifyHeader = "On"
NotifyKeepAliveTime = "30"
//Tag List
TagListFormat = "Text"
TagListAntennaCombine = "On"
TagListMillis = "On"
PersistTime = "-1"
//Tag Stream
TagStreamAddress = "192.168.1.111"
TagStreamFormat = "Text"
TagStreamKeepAliveTime = "30"
TagListMillis = "On"
//IO
IOStreamAddress =
IOStreamFormat = "Text";
IOStreamKeepAliveTime = "30";
IOListFormat = "Text";
設定好 Reader 後可調用 Save 方法,將設定檔存在 Reader
完成 Reader 的設定後接下來我們就可以來寫程式Listening它收集到的結果了,步驟如下:
Step1.初始化 Socket 執行個體:
Step2.調用 Socket.Bind方法:
Step3.調用 Socket.Listen方法:
Step4.調用 Socket.Accept方法:
實作程式碼如下:
public string Listening()
{
if (this._disposed)
{
throw new ObjectDisposedException("SynchronousListening");
}
var ipAddress = IPAddress.Parse(this.HostIpAddress);
var iPEndPoint = new IPEndPoint(ipAddress, this.ListeningPort);
var endPoint = (EndPoint)iPEndPoint;
//create TCP/IP socket.
var clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Bind(endPoint);
clientSocket.Listen(int.MaxValue);
//accept
this._acceptSocket = clientSocket.Accept();
var remote = this._acceptSocket.RemoteEndPoint;
var local = this._acceptSocket.LocalEndPoint;
//get accept receive
this.AcceptReceive = Receive();
return this.AcceptReceive;
}
調用結果如下:
Step5.調用 Socket.Receive 方法,接收 Socket.Accept 的結果:
Receive得依 Server 的特性去處理,千萬別傻傻的抄
public string Receive()
{
if (this._disposed)
{
throw new ObjectDisposedException("SynchronousListening");
}
if (this._acceptSocket == null || !this._acceptSocket.Connected)
{
return null;
}
lock (this._receiveLock)
{
var sb = new StringBuilder();
var buffer = new byte[256];
while (true)
{
var socketError = new SocketError();
var receiveCount = this._acceptSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None, out socketError);
if (receiveCount == 0 || socketError != SocketError.Success)
{
break;
}
else
{
var receive = this.Encode.GetString(buffer, 0, receiveCount);
sb.Append(receive);
if (this._acceptSocket.Available == 0)
{
break;
}
}
}
var result = sb.ToString();
return result;
}
}
Step6.不斷的調用 Socket.Receive 方法
在這裡使用ThreadPool,執行無窮迴圈,不斷的接收Alien Reader發送的訊息,但別忘了要設定離開迴圈的旗標
public void StartListening()
{
if (this._disposed)
{
throw new ObjectDisposedException("SynchronousListening");
}
if (this.IsListening)
{
return;
}
if (string.IsNullOrEmpty(this.AcceptReceive))
{
var listen = Listening();
}
this.IsListening = true;
ThreadPool.QueueUserWorkItem(o =>
{
var e = new MessageEventArgs();
while (true)
{
if (!this.IsListening)
{
break;
}
var receive = Receive();
e.Message = receive;
if (this.ListeningMessage != null)
{
this.ListeningMessage.Invoke(this, e);
}
Thread.Sleep(this.Interval);
}
});
}
public void StopListening()
{
if (this._disposed)
{
throw new ObjectDisposedException("SynchronousListening");
}
if (!this.IsListening)
{
return;
}
this.IsListening = false;
}
完整程式碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace GTS.RFID.C1G2.Alien.Client
{
public class SynchronousListening : IDisposable
{
//fields
private int _interval = 1000;
private Encoding _encode = Encoding.ASCII;
private Socket _acceptSocket;
private bool _disposed = false;
private string _hostIpAddress;
private object _receiveLock = new object();
//properites
public bool IsListening { get; private set; }
public string HostIpAddress
{
get { return _hostIpAddress; }
set
{
IPAddress address;
if (string.IsNullOrEmpty(value))
{
throw new ArgumentNullException("HostIpAddress");
}
if (IPAddress.TryParse(value, out address))
{
_hostIpAddress = value;
}
else
{
throw new Exception("Invalid IpAddress");
}
}
}
public int ListeningPort { get; set; }
public string AcceptReceive { get; private set; }
//events
public event EventHandler<MessageEventArgs> ListeningMessage;
public Encoding Encode
{
get { return _encode; }
set { _encode = value; }
}
public int Interval
{
get { return _interval; }
set { _interval = value; }
}
//constructor
public SynchronousListening(string HostIpAddress, int ListeningPort)
{
this.HostIpAddress = HostIpAddress;
this.ListeningPort = ListeningPort;
}
public string Listening()
{
if (this._disposed)
{
throw new ObjectDisposedException("SynchronousListening");
}
var ipAddress = IPAddress.Parse(this.HostIpAddress);
var iPEndPoint = new IPEndPoint(ipAddress, this.ListeningPort);
var endPoint = (EndPoint)iPEndPoint;
//create TCP/IP socket.
var clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Bind(endPoint);
clientSocket.Listen(int.MaxValue);
//accept
this._acceptSocket = clientSocket.Accept();
var remote = this._acceptSocket.RemoteEndPoint;
var local = this._acceptSocket.LocalEndPoint;
//get accept receive
this.AcceptReceive = Receive();
return this.AcceptReceive;
}
//public method
public void StartListening()
{
if (this._disposed)
{
throw new ObjectDisposedException("SynchronousListening");
}
if (this.IsListening)
{
return;
}
if (string.IsNullOrEmpty(this.AcceptReceive))
{
var listen = Listening();
}
this.IsListening = true;
ThreadPool.QueueUserWorkItem(o =>
{
var e = new MessageEventArgs();
while (true)
{
if (!this.IsListening)
{
break;
}
var receive = Receive();
e.Message = receive;
if (this.ListeningMessage != null)
{
this.ListeningMessage.Invoke(this, e);
}
Thread.Sleep(this.Interval);
}
});
}
public string Receive()
{
if (this._disposed)
{
throw new ObjectDisposedException("SynchronousListening");
}
if (this._acceptSocket == null || !this._acceptSocket.Connected)
{
return null;
}
lock (this._receiveLock)
{
var sb = new StringBuilder();
var buffer = new byte[256];
while (true)
{
var socketError = new SocketError();
var receiveCount = this._acceptSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None, out socketError);
if (receiveCount == 0 || socketError != SocketError.Success)
{
break;
}
else
{
var receive = this.Encode.GetString(buffer, 0, receiveCount);
sb.Append(receive);
if (this._acceptSocket.Available == 0)
{
break;
}
}
}
var result = sb.ToString();
return result;
}
}
public void StopListening()
{
if (this._disposed)
{
throw new ObjectDisposedException("SynchronousListening");
}
if (!this.IsListening)
{
return;
}
this.IsListening = false;
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (this._disposed)
return;
if (disposing)
{
//clean management resource
}
//clean unmanagement resource
this.StopListening();
//change disposed flag
this._disposed = true;
}
//destructor
~SynchronousListening()
{
this.Dispose(false);
}
}
public class MessageEventArgs : EventArgs
{
private string _message;
public string Message
{
get { return _message; }
set { _message = value; }
}
}
}
在 Client 端的調用
private SynchronousListening _listening = new SynchronousListening("192.168.1.111", 7798);
private void button_ListeningTCP_Click(object sender, EventArgs e)
{
_listening.ListeningMessage += _listening_ListeningMessage;
_listening.StartListening();
}
void _listening_ListeningMessage(object sender, MessageEventArgs e)
{
if (InvokeRequired)
{
this.Invoke((MethodInvoker)(() =>
{
this.textBox1.Text = e.Message;
}));
}
}
private void button_StopListeningTCP_Click(object sender, EventArgs e)
{
_listening.StopListening();
}
執行結果如下:
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET