[C#.NET][TCP Socket] 利用 Socket 同步方法 監聽 Alien Reader

  • 14213
  • 0
  • C#
  • 2013-08-16

[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

image


完成 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;
}

 

調用結果如下:

image

 

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();
}



執行結果如下:


image



 

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo