大話-詳解TCP/IP及C#-Socket實(shí)現(xiàn)

1.在Excel上寫(xiě)的內(nèi)容,有TCP連接到斷開(kāi)的解析,直接粘貼出來(lái)


image.png

2.用C#語(yǔ)言來(lái)簡(jiǎn)單實(shí)現(xiàn)TCP連接到斷開(kāi)
①服務(wù)端

namespace TcpServer
{
    /// <summary>
    /// 步驟:綁定服務(wù)器IP和端口->監(jiān)聽(tīng)客戶端連接->傳輸數(shù)據(jù)->關(guān)閉與客戶端的連接
    /// </summary>
    class SimpleServer
    {
        private Socket mSocket = null;

        private SimpleServer mSimpleServer = null;

        private byte[] mReceiveBuffer = null;
        private int mBufferIndex;

        public SimpleServer()
        {
            mSimpleServer = this;

            mReceiveBuffer = new byte[1024];
            mBufferIndex = 0;
        }

        /// <summary>
        /// 綁定ip 和端口
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <returns></returns>
        public SimpleServer Bind(string ip, int port)
        {
            mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            IPAddress iPAddress = IPAddress.Parse(ip);
            IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, port);

            mSocket.Bind(iPEndPoint);

            return mSimpleServer;
        }

        /// <summary>
        /// 開(kāi)始監(jiān)聽(tīng)
        /// </summary>
        /// <param name="queueCount"></param>
        /// <returns></returns>
        public SimpleServer Listen(int queueCount)
        {
            //0:不處理隊(duì)列,>0:最多處理的隊(duì)列長(zhǎng)度。
            mSocket.Listen(queueCount);

            return mSimpleServer;
        }

        /// <summary>
        /// 異步傳輸數(shù)據(jù)(這里暫時(shí)僅實(shí)現(xiàn)異步接收)
        /// </summary>
        /// <returns></returns>
        public SimpleServer StartTransmission()
        {
            mSocket.BeginAccept(AsyncAcceptCallback, mSocket);

            return mSimpleServer;
        }

        private void AsyncAcceptCallback(IAsyncResult ar)
        {
            //獲取自定義的對(duì)象
            Socket socket = ar.AsyncState as Socket;
            //異步接受傳入的連接嘗試,并創(chuàng)建一個(gè)新 Socket 來(lái)處理遠(yuǎn)程主機(jī)通信。
            Socket clientSocket = socket.EndAccept(ar);

            string helloStr = "Hello Client! It is Server!";
            byte[] helloByte = Encoding.UTF8.GetBytes(helloStr);
            clientSocket.Send(helloByte);

            clientSocket.BeginReceive(mReceiveBuffer,
                mBufferIndex,
                RemainSize,
                SocketFlags.None,
                AsyncReceiveCallback,
                clientSocket);

            socket.BeginAccept(AsyncAcceptCallback, socket);
        }

        private void AsyncReceiveCallback(IAsyncResult ar)
        {
            Socket clientSocket = null;
            try
            {
                clientSocket = ar.AsyncState as Socket;
                int count = clientSocket.EndReceive(ar);
                if(count == 0)
                {
                    //接收不到數(shù)據(jù),說(shuō)明客戶端已經(jīng)關(guān)閉,那在服務(wù)端這里要關(guān)閉 Socket
                    clientSocket.Close();
                    Console.WriteLine("客戶端已經(jīng)關(guān)閉");
                    return;
                }
                else
                {
                    MoveBufferIndex(count);
                    ReadReceiveData();
                    clientSocket.BeginReceive(mReceiveBuffer,
                        mBufferIndex,
                        RemainSize,
                        SocketFlags.None,
                        AsyncReceiveCallback,
                        clientSocket);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                if(clientSocket != null)
                {
                    clientSocket.Close();
                    Console.WriteLine("客戶端已經(jīng)關(guān)閉");
                }
            }
            finally
            {
                //有沒(méi)有異常最后都要做的:
            }
        }

        public void CloseServer()
        {
            mSocket.Close();
        }

        /// <summary>
        /// 剩余的 buffer 數(shù)量
        /// </summary>
        private int RemainSize
        {
            get{ return (1024 - mBufferIndex); }
        }

        private void MoveBufferIndex(int value)
        {
            mBufferIndex += value;
        }

        private void ReadReceiveData()
        {
            while(true)
            {
                int length = mBufferIndex - 4;
                if(length <= 0)
                {
                    return;
                }
                int count = BitConverter.ToInt32(mReceiveBuffer, 0);
                if(length >= count)
                {
                    string receiveStr = Encoding.UTF8.GetString(mReceiveBuffer, 4, count);
                    Console.WriteLine("解析接受到的數(shù)據(jù):" + receiveStr);
                    mBufferIndex -= (4 + count);
                    Array.Copy(mReceiveBuffer, 4 + count, mReceiveBuffer, 0, mBufferIndex);
                }
                else
                {
                    return;
                }
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            SimpleServer simpleServer = new SimpleServer();

            simpleServer.Bind("127.0.0.1", 6666)
                .Listen(10)
                .StartTransmission();

            Console.ReadLine();
        }
    }
}

②客戶端

namespace TcpClient
{
    /// <summary>
    /// 過(guò)程:連接服務(wù)端-->數(shù)據(jù)交互-->斷開(kāi)連接
    /// </summary>
    class SimpleClient
    {
        private Socket mSocket = null;

        private SimpleClient mSimpleClient = null;

        private byte[] mReceiveBuffer = null;

        public SimpleClient()
        {
            mSimpleClient = this;

            mReceiveBuffer = new byte[1024];
        }

        public SimpleClient ConnetServer(string ip, int port)
        {
            mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPAddress iPAddress = IPAddress.Parse(ip);
            IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, port);
            mSocket.Connect(iPEndPoint);

            return mSimpleClient;
        }

        public void Receive()
        {
            int count = mSocket.Receive(mReceiveBuffer);
            string receiveMsg = Encoding.UTF8.GetString(mReceiveBuffer, 0, count);
            Console.WriteLine(receiveMsg);
        }

        public void Send(byte[] dataByte)
        {
            mSocket.Send(dataByte);
        }

        public void Close()
        {
            mSocket.Close();
        }
        /// <summary>
        /// 將字符串轉(zhuǎn)換為 byte數(shù)組
        /// </summary>
        /// <param name="dataStr">要轉(zhuǎn)換的字符串</param>
        /// <returns>byte數(shù)組</returns>
        public byte[] String2Bytes(string dataStr)
        {
            byte[] dataByte = Encoding.UTF8.GetBytes(dataStr);
            byte[] dataBytelength = BitConverter.GetBytes(dataByte.Length);
            byte[] newByte = dataBytelength.Concat(dataByte).ToArray();
            return newByte;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            SimpleClient simpleClient = new SimpleClient();
            simpleClient.ConnetServer("127.0.0.1", 6666);
            simpleClient.Receive();
            simpleClient.Send(simpleClient.String2Bytes("send somethings to server..."));
            Console.ReadKey();
            simpleClient.Close();
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容