1. 程式人生 > >JAVA基礎知識|Socket

JAVA基礎知識|Socket

一個數 規範 pre cli break tcp協議 html 一個 buffer

一、什麽是Socket?

Socket本身並不是協議,是一套完成TCP、UDP協議的調用接口(API),通過socket我們才能使用TCP/IP協議(JAVA基礎知識|TCP/IP協議)。Socket的出現只是使得程序員更方便地使用TCP/IP協議棧而已,是對TCP/IP協議的抽象,從而形成了我們知道的一些最基本的函數接口。

Socket連接至少需要一對套接字,其中一個運行於客戶端,稱為ClientSocket ,另一個運行於服務器端,稱為ServerSocket 。

HTTP請求是基於Socket之上的(HTTP是轎車,提供了封裝或者顯示數據的具體形式;Socket是發動機,提供了網絡通信的能力。),總體來說, 只要是涉及到通訊類的應用,都是需要使用Socket, 最著名的就是我們常用的QQ、微信、旺旺等。

二、Socket通信過程

首先我們來看一下瀏覽器向Web服務器發出Http請求以及Web服務器給瀏覽器回復的過程:

1)瀏覽器創建Socket,按給定IP(域名)和端口(默認為80)連接服務器。比如使用類似Socket.Connect()、Socket.BeginConnect()等方法;

2)連接成功後,瀏覽器依據HTTP協議規範(關於協議,後面有講到),向Web服務器發送請求數據。比如“請求行”、“請求頭標”以及“請求數據”等,這裏可能使用類似Socket.Send()、Socket.BeginSend()等方法。

3)瀏覽器等待服務器處理並返回數據;

4)Web服務器端使用Socket.Accept()、Socket.BeginAccept()等方法偵聽到瀏覽器的連接後,便開始接收瀏覽器發送的數據。接收到請求數據後,依據HTTP協議規範解析數據,然後處理,最終將處理結果(如html文檔)發回給瀏覽器,這裏可能用到類似Socket.Send()、Socket.BeginSend()等方法;

5)Web服務器發送完處理結果後,關閉Socket;

6)瀏覽器接收Web服務器發回的數據(如html),將其顯示在瀏覽器UI界面。關閉socket;

7)一次“瀏覽器到Web服務器”的http請求結束;

8)下一次瀏覽器需要請求Web服務器,跳轉到第1)步循環開始。

用圖表示以上過程:

技術分享圖片

三、使用Socket模擬Web服務器

實際Web程序運行過程中,由瀏覽器創建Socket並與Web服務器進行連接,完成數據的交互與傳輸。下面我們使用代碼來模擬實現Web服務器接收Socket請求,並返回請求的過程。當然我們也可以模擬瀏覽器的功能,傳輸內容要符合http協議規定的格式。

            IPAddress address = IPAddress.Loopback;//取得本機的loopback網絡地址,即127.0.0.1
            IPEndPoint endPoint = new IPEndPoint(address, 49152);//創建可訪問的端點,49152表示端口號,如果設置為0,表示使用一個空閑的端口號
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//創建socket,使用IPv4地址,數據通信類型為字節流,TCP協議
            socket.Bind(endPoint);//將socket綁定到一個端點上
            socket.Listen(10);//設置連接隊列的長度
            Console.WriteLine("開始監聽,端口號:{0}", endPoint.Port);
            while (true)
            {
                Socket client = socket.Accept();//開始監聽,這個方法會阻塞線程的執行,直到接受到一個客戶端的請求連接
                Console.WriteLine(client.RemoteEndPoint);//輸出客戶端的地址
                byte[] buffer = new byte[4096];//準備讀取客戶端請求的數據,讀取的數據將保存在一個數組中
                int length = client.Receive(buffer, 4096, SocketFlags.None);//接受數據
                //將請求數據翻譯為UTF-8
                System.Text.Encoding utf8 = System.Text.Encoding.UTF8;
                string requestString = utf8.GetString(buffer, 0, length);
                Console.WriteLine(requestString);//顯示請求
                //回應的狀態行
                string statusLine = "HTTP/1.1 200 OK\r\n";
                byte[] statusLineBytes = utf8.GetBytes(statusLine);
                //準備發送回客戶端的網頁
                string responseBody = "<html><head><title>From Socket Server</title></head><body><h1>Hello world.<h1></body></html>";
                byte[] responseBodyBytes = utf8.GetBytes(responseBody);
                //回應的頭部
                string responseHeader = string.Format("Content-Type:text/html;charset=UTF-8\r\nContent-Length:{0}\r\n", responseBody.Length);
                byte[] responseHeaderBytes = utf8.GetBytes(responseHeader);

                //向客戶端發送狀態信息
                client.Send(statusLineBytes);
                //向客戶端發送回應頭
                client.Send(responseHeaderBytes);
                //頭部與內容的分隔行
                client.Send(new byte[] { 13, 10 });
                //向客戶端發送內容部分
                client.Send(responseBodyBytes);

                //斷開與客戶端的連接
                client.Close();
                if (Console.KeyAvailable)
                    break;
            }
            socket.Close();

技術分享圖片技術分享圖片

JAVA基礎知識|Socket