.net平台下C#socket通訊(中)__.net

來源:互聯網
上載者:User

本文主要講述:

1、正常通訊中握手建立

2、一對多的通訊

3、發送接收資料格式轉換

4、資源釋放

5、開啟並保持服務監聽

 

1、握手建立正常的通訊通道

  項目需要通訊的雙方(假設是一個上位機、一個下位機)之間需要建立一個穩定的通道,以便進行通訊。本項目中具體操作是:上位機作為伺服器,下位機作為用戶端,同時制定通訊協定。上位機首先開啟監聽等待建立通道,下位機主動串連上位機後發送串連成功的資訊到上位機,上位機根據通訊協定發送資料到下位機,此時通道已經建立。但為了保險起見(同時遵循三向交握),用戶端再次發送資料到上位機告知通道建立完畢。

 

2、一對多通訊

  項目需求是一個上位機多個下位機,這就確定了上位機做為伺服器端,下位機作為用戶端主動串連伺服器。一對一通訊時只有一個socket通道,因此無論是上位機還是下位機在發送和接收資料的時候都不會存在資料亂髮亂收的情況。一對多意味著上位機和下位機會建立起多個通道,因此在發送資料時需要記錄哪一個下位機處於哪個socket通道中,以便進行邏輯處理。本文處理一對多通訊的過程是:

1)首先建立一個對話類Session:

public class Session    {        public Socket ClientSocket { get; set; }//用戶端的socket        public string IP;//用戶端的ip        public Session(Socket clientSocket)        {            this.ClientSocket = clientSocket;            this.IP = GetIPString();        }        public string GetIPString()        {            string result = ((IPEndPoint)ClientSocket.RemoteEndPoint).Address.ToString();            return result;        }    }

 

2)在服務端socket監聽時:

IPEndPoint loaclEndPoint = new IPEndPoint(IPAddress.Any, Port);            SocketLister = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            SocketLister.Bind(loaclEndPoint);            try            {                SocketLister.Listen(MaxConnection);                while (IsRunning)                {                    ClientSocket = SocketLister.Accept();                    //儲存socket                    Session newSession = new Session(ClientSocket);                    lock (sessionLock)                    {                        sessionTable.Add(newSession.IP, newSession);                    }                    SocketConnection socketConnection = new SocketConnection(ClientSocket);                    socketConnection.ReceiveDatagram();//接收資料                }            }            catch (SocketException ex)            {            }



//聲明

public Hashtable sessionTable = new Hashtable ();//包括用戶端工作階段

private object sessionLock = new object();

 

為了便於理解,把整個服務端socket的建立都寫在上面。

 

3)發送資料到不同的用戶端

Hashtable ht = serverSocket.sessionTable;            foreach (Session session in ht.Values)            {                if (session.IP == "127.0.0.1")//example                {                    SocketConnection socketConnection = new SocketConnection(session.ClientSocket);                    string str = "C300010002D2";                    byte[] sendBytes = StrToHexByte(str);                    socketConnection.Send(sendBytes);                }                           }

SocketConnection類已經被使用多次,寫在下面:

 

public class SocketConnection:IDisposable     {        public ServerSocket Server { get; set; }        public Byte[] MsgBuffer = null;        private int totalLength = 0;        public int CurrentBufferLength;        private Socket _ClientSocket = null;        public Socket ClientSock        {            get{ return this._ClientSocket; }        }        public SocketConnectionType Type { get; private set; }        #region Constructor        public SocketConnection(ServerSocket server, Socket sock)        {            this.Server = server;            this._ClientSocket = sock;            this.Type = SocketConnectionType.Server;        }        public SocketConnection(Socket sock)        {            this._ClientSocket = sock;            this.Type = SocketConnectionType.Client;        }        #endregion         #region Events        public SocketConnectionDelegate OnConnect = null;//是否串連        public SocketConnectionDelegate OnLostConnect = null;//中斷串連        public ReceiveDataDelegate OnReceiveData = null;//接收資料        #endregion         #region Connect        public void Connect(IPAddress ip, int port)        {            this.ClientSock.BeginConnect(ip, port, ConnectCallback, this.ClientSock);        }        private void ConnectCallback(IAsyncResult ar)        {            try            {                Socket handler = (Socket)ar.AsyncState;                handler.EndConnect(ar);                if (OnConnect != null)                {                    OnConnect(this);                }                ReceiveDatagram();            }            catch (SocketException ex)            {            }        }        #endregion        #region Send        public void Send(string data)        {            Send(System.Text.Encoding.UTF8.GetBytes(data));        }        public void Send(byte[] byteData)        {            try            {                int length = byteData.Length;                byte[] head = BitConverter.GetBytes(length);                byte[] data = new byte[head.Length + byteData.Length];                Array.Copy(head, data, head.Length);                Array.Copy(byteData, 0, data, head.Length, byteData.Length);                this.ClientSock.BeginSend(data, 0, data.Length, 0, new AsyncCallback(SendCallback), this.ClientSock);            }            catch (SocketException ex)            {            }        }        private void SendCallback(IAsyncResult ar)        {            try            {                Socket handler = (Socket)ar.AsyncState;                handler.EndSend(ar);            }            catch (SocketException ex)            {            }        }        #endregion        #region ReceiveDatagram             public void ReceiveDatagram()        {            SocketStateObject state = new SocketStateObject();            state.workSocket = _ClientSocket;            _ClientSocket.BeginReceive(state.buffer, 0, SocketStateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);        }        private void ReceiveCallback(IAsyncResult ar)        {            SocketStateObject state = (SocketStateObject)ar.AsyncState;            Socket handler = state.workSocket;            if (handler.Connected)            {                try                {                    state.bytesRead = handler.EndReceive(ar);                    if (state.bytesRead > 0)                    {                        OnDataRecivedCallback(state.buffer, state.bytesRead);                        Array.Clear(state.buffer, 0, state.buffer.Length);                        state.bytesRead = 0;                        handler.BeginReceive(state.buffer, 0, SocketStateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);                    }                    else                    {                        //
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.