1. 程式人生 > >戲說TCP網絡編程

戲說TCP網絡編程

ont byname tcp 傳輸數據 code mission () prot pri

1、何為TCP
既然說到TCP協議網絡編程,那麽首先來了解下什麽是TCP協議。
TCP協議的全稱叫Transmission Control Protocol 傳輸控制協議,
是一種面向連接的、可靠的、基於字節流的傳輸層通信協議。在因特網協議族(Internet protocol suite)中,TCP層是位於IP層之上。
面向連接是什麽呢?面向連接可以理解為指定對象,就好像平時打電話一樣,你要打電話需要電話號碼,也就是需要指定打電話的對象;可靠就簡單了,就是在傳輸的過程中不會受到外界因素的印象;基於字節流也就是在傳輸數據的過程中是通過字節流來完成的。
2、與兄弟UDP區別
TCP協議有個兄弟叫UDP,那麽怎麽又來了個UDP呢?UDP可以認為是區別於TCP的存在的。剛才說TCP類似於打電話,那麽UDP就類似於廣播;TCP需要先連接才可以傳數據,而UDP是廣播,也就是說我只管發送數據,不管你到底有沒有接收到,所以TCP是可靠的,UDP是不可靠的;如果按照人物性格區分的話,那麽TCP就可以認為是一個內向的,而UDP是一個外向的。
3、初入門-TCP編程初窺
說了這麽多,開始咱們今天的主要內容吧,首先咱們來看一下TCP網絡編程的使用步驟吧。
還拿打電話來說,那麽咱們打電話時候都是什麽步驟呢?首先,準備好要撥打的電話號碼,然後撥打電話後等待對方接通,當對方接通之後,就可以進行通話了。那麽咱們拿撥打方稱為客戶端,被叫方稱為服務端,就可以來整理TCP的步驟了,首先咱們需要準備一個IP地址(被叫電話號碼),使用InetAddress類來處理;既然是撥打就需要準備電話了,使用Socket來處理,然後等待服務端(被叫方)接通,同樣需要對應的類ServerSocket來處理;當連接(接通)後開始傳輸數據(通話),就用到字節流了。
那麽,下面咱們開始代碼作業了:
首先是客戶端代碼(只復制方法內容):

try {
            //準備要訪問的服務器IP地址(也就是要撥打的電話號碼,以本地ip為例)
            InetAddress ia = InetAddress.getByName("127.0.0.1");
            //創建Socket對象(電話機),需要制定端口號,8806就是端口號(端口號相當於分機)
            Socket s = new Socket(ia, 8806);
            //準備要傳輸的數據,(要通話的內容)
            String data="Hello,I am TCP !";
            //因為是基於字節流的,所以需要把字符串轉換為字節數組 
            byte[] bytes = data.getBytes();
            //創建輸出流對象
            OutputStream out = s.getOutputStream();
            //傳輸數據(說出通話內容)
            out.write(bytes);
            out.flush();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

接著是服務端代碼(只復制方法內容):

    try {
            //創建服務端ServerSocket對象
            ServerSocket ss =  new ServerSocket(8806);
            //等待連接(等待別人撥打這個號碼),當有人連接時返回連接socket對象
            Socket s = ss.accept();
            //通過獲取到的連接Socket對象來獲取包含客戶端發送數據的輸入流對象
            InputStream in = s.getInputStream();
            //創建放置數據的緩沖區
            byte[] bys = new byte[1024];
            //讀取客戶端發送的數據
            int length = in.read(bys);
            //輸出到控制臺
                System.out.println("客戶端 :" + new            String(bys,0,length));      
    } catch (IOException e) {
            e.printStackTrace();
        }

接著就是見證奇跡的時刻,我們一起來看運行結果吧,需要註意:一定要先運行服務端的代碼,然後運行客戶端的代碼。

技術分享圖片
4、進擊篇-TCP客戶端和服務端互通數據
上文提到的只是客戶端向服務端發送數據,那麽咱們能不能讓它們之間進行數據相互傳送呢?剛才說了,TCP是面向連接的,基於字節流的,所以當連接建立好以後,我們只管將數據通過字節流進行傳輸就可以了。
進擊的客戶端代碼(只復制方法內容):

try {
            //準備要訪問的服務器IP地址(也就是要撥打的電話號碼)
            InetAddress ia = InetAddress.getByName("127.0.0.1");
            //創建Socket對象(電話機),需要制定端口號,8806就是端口號(端口號相當於分機)
            Socket s = new Socket(ia, 8806);
            //準備要傳輸的數據,(要通話的內容)
            String data="Hello,I am TCP !";
            //因為是基於字節流的,所以需要把字符串轉換為字節數組 
            byte[] bytes = data.getBytes();
            //創建輸出流對象
            OutputStream out = s.getOutputStream();
            //輸出電話內容
            out.write(bytes);
            out.flush();
            //從連接的Socket對象中獲取輸入流
            InputStream inputStream = s.getInputStream();
            byte[] bys = new byte[1024];
            //讀取服務端發送的數據
            int length = inputStream.read(bys);
            //輸出到控制臺
            System.out.println("服務端 :" + new String(bys,0,length));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

同樣的服務端代碼(只復制方法內容):

try {
            //創建服務端ServerSocket對象
            ServerSocket ss =  new ServerSocket(8806);
            //等待連接(等待別人撥打這個號碼),當有人連接時返回連接socket對象
            Socket s = ss.accept();
            //通過獲取到的連接Socket對象來獲取包含客戶端發送數據的輸入流對象
            InputStream in = s.getInputStream();
            //創建放置數據的緩沖區
            byte[] bys = new byte[1024];
            //讀取客戶端發送的數據
            int length = in.read(bys);
            //輸出到控制臺
            System.out.println("客戶端 :" + new String(bys,0,length));
            //準備要傳輸的數據,(要通話的內容)
            String data="Hello,I am server !";
            //因為是基於字節流的,所以需要把字符串轉換為字節數組 
            byte[] bytes = data.getBytes();
            //創建輸出流對象
            OutputStream out = s.getOutputStream();
            //輸出電話內容
            out.write(bytes);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }

再一次見證奇跡:
服務端
技術分享圖片
客戶端
技術分享圖片

需要說明的是,咱們演示的只是獲取一次數據,不管是客戶端和服務端都是發送和獲取都是一次。在現實生活中,打電話不會是雙方直說一句話,所以需要註意,如果要達到這個效果的話,我們需要使用循環來包裹字節輸入輸出流部分的代碼就搞定了。

戲說TCP網絡編程