TCP UDP、Socket

回過頭來看到自己寫的東西真是太糟糕了,剛開始的初衷是希望能夠寫一些有用的文章,不管是自己偶爾看看或者是別的朋友不經意間看到,都能或多或少有點收穫,可是現在看來,學藝也不精,理解也不深,就寫了很多沒用的東西,從頭看到尾滿滿的水分。。。學無止盡,共勉。
2017/01/17


TCP UDP

TCP(Transmission Control Protocol 傳輸控制協議)

優點在於信息傳輸的穩定性、可靠性,傳輸前進行三次握手確定連接;
缺點在於效率相對較低,且頭部較大。

UDP(User Data Protocol,用戶數據報協議)

傳輸數據時大小被限定在64KB之內;
優點在於傳輸速度較快,指定地址和端口號就能直接傳輸數據;
缺點在於傳輸前沒有連接確認,有可能會出現丟包的現象。

TCP和UDP都是傳輸層的協議,區別在傳輸前是否需要進行連接,可以把TCP和UDP分別理解成電話和短信。TCP(電話)在數據傳輸前要先建立通信,一方發起通信,另一方進行確認,確認通信成功後才能進行數據傳輸,傳輸完成後再斷開連接,所以數據的傳輸時穩定可靠的,但是建立通信會降低一定的效率;而UDP(短信)相對來說比較快,不需要建立連接就能直接發送數據,只需要指定一個接收方,但是相對而言也不能確認對方是否收到數據。


Socket

先展示一段簡單的C/S的socket通信代碼
服務端核心代碼
try{
    ServerSocket serverSocket = new ServerSocket(8888);
    Socket socket = serverSocket.accept();
    InputStream inputStream = socket.getInputStream();
    // 將字節流轉爲字符流
    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
    String temp; 
    while((temp = bufferedReader.readLine()) != null){
        System.out.println(temp);
    }
    bufferedReader.close();
    inputStream.close();
} catch (Exception e){
    e.printStackTrace();
}
客戶端核心代碼
try{
    String str = "Hello,Server";
    Socket socket =new Socket("192.168.64.39",8888);
    OutputStream outputStream = socket.getOutputStream();
    byte[] b = str.getBytes();
    outputStream.write(b);
    outputStream.flush();
    outputStream.close();
} catch (Exception e){
    e.printStackTrace();
}

Socket是對TCP/IP進行封裝後的變成接口,通過它可以實現兩臺設備的通信。Socket都是成對出現的,描述了要連接的IP、端口對,即知道對方的IP以及端口就可以給對方發送消息。
單向的socket通信過程:
1)服務端利用Socket監聽端口;
2)客戶端發起連接;
3)客戶端向服務端發送數據;
4)客戶端,服務端斷開連接。

java中的Socket類有兩個方法isConnected()和isClosed(),在使用的時候有幾點需要注意的。
isConnect()返回的不是socket當前是否連接的狀態,而是曾經是否建立過連接。
isClosed()返回的是socket當前是否已經關閉連接的狀態,連接中的socket調用close()方法、關閉輸入輸出流、斷網都會導致連接中的socket狀態改變。

在閱讀源碼的時候發現不同的JDK對Socket.close()的處理是不一樣的,需要注意

java\net\Socket.java(android-23)

public synchronized void close() throws IOException {
    isClosed = true;
    isConnected = false;
    // RI compatibility: the RI returns the any address (but the original local port) after
    // close.
    localAddress = Inet6Address.ANY;
    impl.close();
    }
java\net\Socket.java(java-1.8)

public synchronized void close() throws IOException {
    synchronized(closeLock) {
    if (isClosed())
        return;
    if (created)
        impl.close();
    closed = true;
    }
}

也就是說AndroidSDK下的java代碼中,調用socket.close()再調用socket.isConnected(),返回值爲false。

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