Socket網絡編程

開篇廢話

身爲一個優(cai)秀(niao)的自學java的存在,網絡編程怎麼能不懂呢?所以咱今天就談談這個網絡編程,也不知道談的對不對,總要先談一談嘛。我看了衆多的教程,都是專業名詞、專業解釋先給你一通砸下來,先砸蒙了你,讓你不禁發出靈魂三問:我是誰?我在哪?我在幹什麼?他說的啥?這句話每個字都認識,但是合起來爲什麼就不認識了呢?於是乎,今天,我就打破常規,用最通俗的語言來談一談網絡編程。

學習前提

什麼ip地址啊,域名啊,端口號啊,協議啊,這些的就不用解釋了吧,畢竟連我這麼優(cai)秀(niao)的自學者都知道,真不知道可以查一查,很簡單的。還有Java編程總會吧,類和對象總知道吧。在Java裏不就是給了你一個類,然後這個類有幾個方法,都是幹什麼的,怎麼用,不就這些嗎?我們要學會俯視它。

正文開始之前的廢話

我們就先從最簡單的開始吧,什麼是網絡通信,沒錯就是一臺機器給另一臺機器通過網絡發送數據的,這總能理解吧。能發送數據了,不就能建立通信了,大家不就能聯繫了?閒話都說了這麼多了,那我就再說一些,大家搜索socket的時候,發現都說它是套接字,很神奇吧,這三個字都認識,連在一起就有點不認識了。明明它的翻譯是插座,爲什麼要翻譯成套接字呢?假如我們把它翻譯成插座,服務器就是一個大插座,客戶端就是插頭,一方被插,一方去插,然後建立通信,這樣不是很好理解嗎?至於爲什麼翻譯成套接字,據知乎一位自稱刻(wu)苦(liao)鑽(tou)研(ding)的IT狗說,這......不......可.....考........。不過呢,我相信,它被翻譯成套接字,肯定有它的道理,很有可能,它不止是通信插座這麼簡單。

真的正文開始了

沒辦法,我還是想再聊一聊,畢竟學習這麼枯燥,我再把文章寫得枯燥,那生活就太難了。

我們爲什麼要用socket進行網絡編程呢,回答這個問題之前呢,不得不先回憶一下曾經上課也沒聽過的計算機網絡的知識,什麼OSI七層協議啊,TCP五層協議啊,不知道的可以查一查。根據我曾經的零散記憶,我們寫的應用程序屬於應用層,而TCP/UDP屬於運輸層,那我們怎麼用運輸層的協議呢?沒錯,就是用socket,它介於傳輸層與應用層之間,使我們不用知道運輸層協議細節,直接調用就完事了。

真真正正的正文開始了

不說廢話了,我們直接開始Java裏的網絡編程 ,我們先介紹一個類DatagramSocket,它就是用於既能發送又能接收數據包的類,當然要想發送數據,這個數據也不是你隨隨便便寫個字符串就能發送過去的,還得用另一個類DatagramPacket,我們需要把發送的數據封裝成這個DatagramPacket才能通過DatagramSocket發送到指定目的地。

二話不說先上代碼:

public class StudySocket {
    public static void main(String[] args) throws IOException {

        //定義要發送的數據
        String content = "只要我E的夠快,隊友的問號就追不上我 --快樂的亞索";
        //創建DatagramSocket對象,指定8081端口,默認本機地址,模擬發送端
        DatagramSocket datagramSocket = new DatagramSocket(8081);
        //將發送的數據轉成字節數組
        byte[] data = content.getBytes();
        //使用DatagramPacket,將字節數組打包發送到指定地址
        DatagramPacket packet = new DatagramPacket(data,data.length,
                new InetSocketAddress("localhost",8080));
        //發送數據包
        datagramSocket.send(packet);
        //關閉socket
        datagramSocket.close();
    }
}

代碼解釋:

第一步:定義我們要發送的數據,然後使用DatagramSocket創建一個對象並綁定端口號,模擬發送端。

第二步:將發送的數據轉成字節數組並將其封裝成DatagramPacket,這個類的構造器有很多,我選擇的這個有三個參數,第一個是字節數組,就是你要發送的數據,第二個參數就是該字節的長度,第三個參數就是你要發送的地址,沒錯就是本機的8080端口,我要發送到這裏。InetSocketAddress這個類也不用多說吧,不知道的查一查嘛。

第三步:執行發送命令。

第四步:關閉socket。

如此你就可以運行一下試試,運行之後會發生什麼呢?當然是什麼也沒有發生,我也就不截圖了,那我們發送過去了嗎?發送過去了。那麼數據呢?丟了!沒錯,本機的8080端口又沒有打開,沒有地方接收,它當然就丟了。誒?,看到這裏你是不是就想到了什麼,UDP協議,沒錯,是他,是他,就是他,這個就是使用UDP協議的socket,發送前不需要連接,只管發送,不管你到底接沒接收,反正我就是發了。

接下來,就寫一個接收端,用來接收發送過來的數據,直接看代碼吧

public class SocketServer {
    public static void main(String[] args) throws IOException {
        //創建DatagramSocket對象,綁定8080端口,默認本機地址,模擬接收端
        DatagramSocket datagramSocket = new DatagramSocket(8080);
        //創建字節數組用來接收數據包裏的數據,
        byte[] data = new byte[1024*60];
        //創建DatagramPacket,用來接收數據包
        DatagramPacket packet = new DatagramPacket(data,data.length);
        //接收數據包
        datagramSocket.receive(packet);
        //獲取數據包裏的數據
        data = packet.getData();
        //將字節數組轉爲String並輸出
        System.out.println(new String(data));
        //關閉socket
        datagramSocket.close();
    }
}

先啓動接收端,然後接收端就會阻塞,一直等那個數據包發送過來,再啓動發送端,我們就會看到,接收端真的接收到了數據

有圖有真相。

說起來這個UDP,不得不說起這個TCP,我們看到了,這個UDP不用連接,數據說發送就發送,都不帶商量的。但是TCP就不一樣了,TCP是先建立連接,然後再發送。話不多說,咱直接用代碼來看效果

public class TcpSocket {
    public static void main(String[] args) throws IOException {
        //模擬客戶端與本機的8080端口建立連接
        Socket socket = new Socket("localhost",8080);
        //關閉連接
        socket.close();
    }
}

這個代碼就簡單了很多,直接實例化一個socket就能建立連接,當然,數據就先不發送了,我們先運行一下,看看能不能連接上,運行之前我們先猜想一下,我要跟8080端口建立連接,但是目前我並沒有綁定8080端口的服務,也就是說肯定是連接不上的,那麼連接不上會發生什麼呢?看圖說話

看到了吧,直接報錯,連接不上。這下有沒有體會到TCP和UDP的區別?

這是發送端,我們再建立一個服務端,用來接收服務,這個接收端就需要一個類ServerSocket,我們直接看到代碼吧

public class TcpServer {
    public static void main(String[] args) throws IOException {
        //建立接收端,監聽8080端口
        ServerSocket serverSocket = new ServerSocket(8080);
        //開始接收,到這裏就會阻塞,等待發送端建立連接
        serverSocket.accept();
        System.out.println("連接成功");
        //關閉連接
        serverSocket.close();
    }
}

接收端也很簡單,調用accept()方法,等待連接。這樣先啓動接收端,再啓動發送端,就能建立連接了。

結束語

當然,網絡編程不是隻有這麼一點點,這只是簡簡單單的入個門,理解理解,接下來還有大量的、深入的知識需要學習,路漫漫其修遠兮,且行且珍惜。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章