天天看點

Socket常見問題(Java)

參考連結:https://blog.csdn.net/u014800094/article/details/60591852
           

1、TCP和UDP的差別?

1)TCP提供面向連接配接的傳輸,通信前要先建立連接配接(三次握手機制);UDP提供無連接配接的傳輸,通信前不需要建立連接配接。

2)TCP提供可靠的傳輸(有序,無差錯,不丢失,不重複);UDP提供不可靠的傳輸。

3)TCP面向位元組流的傳輸,是以它能将資訊分割成組,并在接收端将其重組;UDP是面向資料報的傳輸,沒有分組開銷。

4)TCP提供擁塞控制和流量控制機制;UDP不提供擁塞控制和流量控制機制。

2、流量控制和擁塞控制的實作機制?

1)TCP采用大小可變的滑動視窗機制實作流量控制功能。視窗的大小是位元組。在TCP封包段首部的視窗字段寫入的數值就是目前給對方設定發送視窗的資料的上限。

在資料傳輸過程中,TCP提供了一種基于滑動視窗協定的流量控制機制,用接收端接收能力(緩沖區的容量)的大小來控制發送端發送的資料量。

2)采用滑動視窗機制還可對網絡進行擁塞控制,将網絡中的分組(TCP封包段作為其資料部分)數量維持在一定的數量之下,當超過該數值時,網絡的性能會急劇惡化。

傳輸層的擁塞控制有慢開始(Slow-Start)、擁塞避免(Congestion Avoidance)、快重傳(Fast Retransmit)和快恢複(Fast Recovery)四種算法。

擁塞: 大量資料報湧入同一交換節點(如路由器),導緻該節點資源耗盡而必須丢棄後面到達的資料報時,就是擁塞。

3、重傳機制?

TCP每發送一個封包段,就設定一次定時器。隻要定時器設定的重發時間到而還沒有收到确認,就要重發這一封包段。

TCP環境

封包往返時間不定、有很大差别

A、B在一個區域網路絡,往返時延很小

A、C在一個網際網路内,往返時延很大

是以,A很難确定一個固定的、與B、C通信都适用的定時器時間

TCP采用了一種自适應算法。這種算法記錄每一個封包段發出的時間,以及收到相應的确認封包段的時間。

這兩個時間之差就是封包段的往返時延。将各個封包段的往返時延樣本權重平均,就得出封包段的平均往返時延T。

4、滑動視窗機制?

TCP 采用大小可變的滑動視窗進行流量控制。視窗大小的機關是位元組。

在 TCP 封包段首部的視窗字段寫入的數值就是目前給對方設定的發送視窗數值的上限。

發送視窗在連接配接建立時由雙方商定。但在通信的過程中,接收端可根據自己的資源情況,随時動态地調整對方的發送視窗上限值(可增大或減小)。

5、信号與信号量的差別?

1.信号:(signal)是一種處理異步事件的方式。信号時比較複雜的通信方式,用于通知接受程序有某種事件發生,除了用于程序外,還可以發送信号給程序本身。linux除了支援unix早期的信号語義函數,還支援語義符合posix.1标準的信号函數sigaction。

2.信号量:(Semaphore)程序間通信處理同步互斥的機制。是在多線程環境下使用的一種設施, 它負責協調各個線程, 以保證它們能夠正确、合理的使用公共資源。

6、程序和線程的差別?

線程是指程序内的一個執行單元,也是程序内的可排程實體,差別:

(1)排程:線程作為排程和配置設定的基本機關,程序作為擁有資源的基本機關。

(2)并發性:不僅程序之間可以并發執行,同一個程序的多個線程之間也可并發執行。

(3)擁有資源:程序是擁有資源的一個獨立機關,線程不擁有系統資源,但可以通路隸屬于程序的資源.

(4)系統開銷:在建立或撤消程序時,由于系統都要為之配置設定和回收資源,導緻系統的開銷明顯大于建立或撤消線程時的開銷。

7、程序間通訊的方式有哪些,各有什麼優缺點?

1)管道:管道是一種半雙工的通信方式,資料隻能單向流動,而且隻能在具有親緣關系的程序之間使用。程序的親緣關系通常是指父子程序關系。

2)有名管道(FIFO):有名管道也是半雙工的通信方式,但是允許在沒有親緣關系的程序之間使用,管道是先進先出的通信方式。

3)信号量:信号量是一個計數器,可以用來控制多個程序對共享資源的通路。它常作為一種鎖機制,防止某程序正在通路共享資源時,其他程序也通路該資源。是以,主要作為程序間以及同一程序内不同線程之間的同步手段。

4)消息隊列:消息隊列是有消息的連結清單,存放在核心中并由消息隊列辨別符辨別。消息隊列克服了信号傳遞資訊少、管道隻能承載無格式位元組流以及緩沖區大小受限等缺點。

5)信号 ( sinal ) :信号是一種比較複雜的通信方式,用于通知接收程序某個事件已經發生。

6)共享記憶體( shared memory ) :共享記憶體就是映射一段能被其他程序所通路的記憶體,這段共享記憶體由一個程序建立,但多個程序都可以通路。共享記憶體是最快的 IPC 方式,它是針對其他程序間通信方式運作效率低而專門設計的。它往往與其他通信機制,如信号量,配合使用,來實作程序間的同步和通信。

7)套接字( socket ) :套接字也是一種程序間通信機制,與其他通信機制不同的是,它可用于不同機器間的程序通信。

8、TCP連接配接建立的時候3次握手的具體過程,以及每一步原因?

(1)第一步:源主機A的TCP向主機B發出連接配接請求封包段,其首部中的SYN(同步)标志位應置為1,表示想與目标主機B進行通信,并發送一個同步序列号X(例:SEQ=100)進行同步,表明在後面傳送資料時的第一個資料位元組的序号是X+1(即101)。SYN同步封包會指明用戶端使用的端口以及TCP連接配接的初始序号。

(2)第二步:目标主機B的TCP收到連接配接請求封包段後,如同意,則發回确認。在确認報中應将ACK位和SYN位置1,表示用戶端的請求被接受。确認号應為X+1(圖中為101),同時也為自己選擇一個序号Y。

(3)第三步:源主機A的TCP收到目标主機B的确認後要向目标主機B給出确認,其ACK置1,确認号為Y+1,而自己的序号為X+1。TCP的标準規定,SYN置1的封包段要消耗掉一個序号。

  運作客戶程序的源主機A的TCP通知上層應用程序,連接配接已經建立。當源主機A向目标主機B發送第一個資料封包段時,其序号仍為X+1,因為前一個确認封包段并不消耗序号。

  當運作服務程序的目标主機B的TCP收到源主機A的确認後,也通知其上層應用程序,連接配接已經建立。至此建立了一個全雙工的連接配接。

9、TCP斷開連接配接的具體過程,其中每一步是為什麼那麼做?

1)第一步:源主機A的應用程序先向其TCP發出連接配接釋放請求,并且不再發送資料。TCP通知對方要釋放從A到B這個方向的連接配接,将發往主機B的TCP封包段首部的終止比特FIN置1,其序号X等于前面已傳送過的資料的最後一個位元組的序号加1。

2)第二步:目标主機B的TCP收到釋放連接配接通知後即發出确認,其序号為Y,确認号為X+1,同時通知高層應用程序,這樣,從A到B的連接配接就釋放了,連接配接處于半關閉狀态,相當于主機A向主機B說:“我已經沒有資料要發送了。但如果還發送資料,我仍接收。”此後,主機B不再接收主機A發來的資料。但若主機B還有一些資料要發送主機A,則可以繼續發送。主機A隻要正确收到資料,仍應向主機B發送确認。

3)第三步:若主機B不再向主機A發送資料,其應用程序就通知TCP釋放連接配接。主機B發出的連接配接釋放封包段必須将終止比特FIN和确認比特ACK置1,并使其序号仍為Y,但還必須重複上次已發送過的ACK=X+1。

4) 第四步:主機A必須對此發出确認,将ACK置1,ACK=Y+1,而自己的序号是X+1。這樣才把從B到A的反方向的連接配接釋放掉。主機A的TCP再向其應用程序報告,整個連接配接已經全部釋放。

10、TCP建立連接配接和斷開連接配接的各種過程中的狀态轉換細節?

用戶端:主動打開SYN_SENT ---> ESTABLISHED ---> 主動關閉FIN_WAIT_1 ---> FIN_WAIT_2 ---> TIME_WAIT
伺服器端:LISTEN(被動打開)---> SYN_RCVD ---> ESTABLISHED ---> CLOSE_WAIT(被動關閉) ---> LAST_ACK ---> CLOSED

11、ThreadLocal與其它同步機制的比較?

Threadlocal和其他所有的同步機制都是為了解決多線程中的對同一變量的通路沖突,在普通的同步機制中,是通過對對象加鎖來實作多個線程對同一變量的安全通路的。這時該變量是多個線程共享的,使用這種同步機制需要很細緻的分析在什麼時候對變量進行讀寫,什麼時候需要鎖定某個對象,什麼時候釋放該對象的索等等。所有這些都是因為多個線程共享了該資源造成的。Threadlocal就從另一個角度來解決多線程的并發通路,Threadlocal會為每一個線程維護一個和該線程綁定的變量副本,進而隔離了多個線程的資料共享,每一個線程都擁有自己的變量副本,進而也就沒有必要對該變量進行同步了。ThreadLocal提供了線程安全的共享對象,在編寫多線程代碼時,可以把不安全的變量封裝進ThreadLocal。

總結:當然ThreadLocal并不能替代同步機制,兩者面向的問題領域不同。同步機制是為了同步多個線程對相同資源的并發通路,是為了多個線程之間進行通信的有效方式;而ThreadLocal是隔離多個線程的資料共享,從根本上就不在多個線程之間共享資源(變量),這樣當然不需要對多個線程進行同步了。是以,如果你需要進行多個線程之間進行通信,則使用同步機制;如果需要隔離多個線程之間的共享沖突,可以使用ThreadLocal,這将極大地簡化你的程式,使程式更加易讀、簡潔。

12、記憶體池、程序池、線程池?

自定義記憶體池的思想通過這個"池"字表露無疑,應用程式可以通過系統的記憶體配置設定調用預先一次性申請适當大小的記憶體作為一個記憶體池,之後應用程式自己對記憶體的配置設定和釋放則可以通過這個記憶體池來完成。隻有當記憶體池大小需要動态擴充時,才需要再調用系統的記憶體配置設定函數,其他時間對記憶體的一切操作都在應用程式的掌控之中。 應用程式自定義的記憶體池根據不同的适用場景又有不同的類型。 從線程安全的角度來分,記憶體池可以分為單線程記憶體池和多線程記憶體池。單線程記憶體池整個生命周期隻被一個線程使用,因而不需要考慮互斥通路的問題;多線程記憶體池有可能被多個線程共享,是以則需要在每次配置設定和釋放記憶體時加鎖。相對而言,單線程記憶體池性能更高,而多線程記憶體池适用範圍更廣。

從記憶體池可配置設定記憶體單元大小來分,可以分為固定記憶體池和可變記憶體池。所謂固定記憶體池是指應用程式每次從記憶體池中配置設定出來的記憶體單元大小事先已經确定,是固定不變的;而可變記憶體池則每次配置設定的記憶體單元大小可以按需變化,應用範圍更廣,而性能比固定記憶體池要低。

13、多線程如何同步?

采用:臨界區、互斥區、事件、信号量四種方式。

其中臨界區(Critical Section)、互斥量(Mutex)、信号量(Semaphore)、事件(Event)的差別如下:

1)、臨界區:通過對多線程的串行化來通路公共資源或一段代碼,速度快,适合控制資料通路。在任意時刻隻允許一個線程對共享資源進行通路,如果有多個線程試圖通路公共資源,那麼在有一個線程進入後,其他試圖通路公共資源的線程将被挂起,并一直等到進入臨界區的線程離開,臨界區在被釋放後,其他線程才可以搶占。

2)、互斥量:采用互斥對象機制。 隻有擁有互斥對象的線程才有通路公共資源的權限,因為互斥對象隻有一個,是以能保證公共資源不會同時被多個線程通路。互斥不僅能實作同一應用程式的公共資源安全共享,還能實作不同應用程式的公共資源安全共享 .互斥量比臨界區複雜。因為使用互斥不僅僅能夠在同一應用程式不同線程中實作資源的安全共享,而且可以在不同應用程式的線程之間實作對資源的安全共享。

3)、信号量:它允許多個線程在同一時刻通路同一資源,但是需要限制在同一時刻通路此資源的最大線程數目 .信号量對象對線程的同步方式與前面幾種方法不同,信号允許多個線程同時使用共享資源,這與作業系統中的PV操作相同。它指出了同時通路共享資源的線程最大數目。它允許多個線程在同一時刻通路同一資源,但是需要限制在同一時刻通路此資源的最大線程數目。

PV操作及信号量的概念都是由荷蘭科學家E.W.Dijkstra提出的。信号量S是一個整數,S大于等于零時代表可供并發程序使用的資源實體數,但S小于零時則表示正在等待使用共享資源的程序數。

   P操作申請資源:

  (1)S減1;

  (2)若S減1後仍大于等于零,則程序繼續執行;

  (3)若S減1後小于零,則該程序被阻塞後進入與該信号相對應的隊列中,然後轉入程序排程。

  

  V操作 釋放資源:

  (1)S加1;

  (2)若相加結果大于零,則程序繼續執行;

  (3)若相加結果小于等于零,則從該信号的等待隊列中喚醒一個等待程序,然後再傳回原程序繼續執行或轉入程序排程。

4)、事 件: 通過通知操作的方式來保持線程的同步,還可以友善實作對多個線程的優先級比較的操作 .

總結:

  1) 互斥量與臨界區的作用非常相似,但互斥量是可以命名的,也就是說它可以跨越程序使用。是以建立互斥量需要的資源更多,是以如果隻為了在程序内部是用的話使用臨界區會帶來速度上的優勢并能夠減少資源占用量。因為互斥量是跨程序的互斥量一旦被建立,就可以通過名字打開它。

  2) 互斥量(Mutex),信号燈(Semaphore),事件(Event)都可以被跨越程序使用來進行同步資料操作,而其他的對象與資料同步操作無關,但對于程序和線程來講,如果程序和線程在運作狀态則為無信号狀态,在退出後為有信号狀态。是以可以使用WaitForSingleObject來等待程序和線程退出。

  3) 通過互斥量可以指定資源被獨占的方式使用,但如果有下面一種情況通過互斥量就無法處理,比如現在一位使用者購買了一份三個并發通路許可的資料庫系統,可以根據使用者購買的通路許可數量來決定有多少個線程/程序能同時進行資料庫操作,這時候如果利用互斥量就沒有辦法完成這個要求,信号燈對象可以說是一種資源計數器。