OSI七層
物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層、應用層。
物理層涉及信道上傳輸的比特流。
數據鏈路層的主要任務是加強物理層傳輸原始比特流的功能,是指對應的網路層顯現為一條無錯線路。發送包把數據封裝在數據幀,按順序傳送出去并處理接收方會送的確認幀。
網絡層關系到子網的運行控制,其中一個關鍵問題是確認從源端到目的算如何選擇路由。
傳輸層的基本功能是從會話層接收數據而且把其分成較小的單元傳遞給網絡層。
會話層允許不同機器上的用戶建立會話關系。
表示層用來完成某些特定的功能。
應用層包含著大量人們普遍需要的協議。
TCP和UDP
TCP是傳輸控制協議,提供的是面向連接、可靠的字節流服務。當客戶和服務器彼此交換數據前,必須現在雙方,之間建立一個TCP連接,之后才能傳輸數據。TCP提供超時重發、丟棄重讀數據、檢驗數據、流量控制等功能,保證數據能從一端傳到另一端。
UDP是用戶數據報協議,是一個簡單地面向數據報的運輸協議。UDP不提供可靠性,它只是把應用程序傳給IP層的數據報發送出去,但是并不保證它們能夠到達目的地。由于UDP在傳輸數據報前不用在客戶和服務器之間建立一個連接,且沒有超時重發等機制,故而傳輸速度快。
TCP就像是打電話,兩者之間必須有一條不間斷的通路,數據不到達對方,對方就一直在等待,除非對方直接掛電話。先說的話先到,后說的話后到,有順序。
UDP就像寄一封信,發現者只管發,不管到。但是你的新風尚必須寫明對方的資質。發現者和收信者之間沒有通路,靠郵電局聯系。信發到時可能已經過了很久,也可能根本沒有發到。先發的信未必先到,后發的信也未必后到。
Socket套接字
Socket相當于進行網絡通信兩端的插座,只要對方的Socket和自己的Socket有通信聯接,雙方就可以發送和接收數據了。其定義類似于文件句柄的定義。如果你要編寫的是一個服務程序,那么先調用socket()創建一個套接字,調用bind()綁定IP地址和端口號,然后啟動一個死循環,循環中調用accept()接受連接。對于每個接受的鏈接,可以啟動多線程方式進行處理,在線程中調用send()、recv()發送和接收數據。
如果要編寫的是一個客戶端程序,那么久簡單多了,先調用socket()創建一個套接字,然后調用connect()鏈接服務器,之后就是調用send()、recv()發送和接受數據了。
服務器端程序編寫:
1. 調用ServerSocket(int port)創建一個服務器端套接字,并綁定到制定端口上。
2. 調用accept(),監聽連接請求,則接收連接,返回通信套接字。
3. 調用Socket類的getOutStream()和getInputStream()獲取輸出流和輸入流,開始網絡數據的發送和接收。
4. **關閉通信套接字**Socket.close()。
客戶端程序編寫:
1. 調用Socket()創建一個流套接字,并連接到服務器端。
2. 調用Socket類的getOutStream()和getInputStream()獲取輸出流和輸入流,開始網絡數據的發送和接收。
3. **關閉通信套接字**Socket.close()。
TCP三次握手四次握手
在TCP/IP協議中,TCP協議提供可靠的連接服務,采用3次握手建立一個連接。
第1次握手:建立連接時,客戶端發送SYN包(syn=j)到服務器,并進入SYN_SEND狀態,等待服務器確認。
第2次握手:服務器收到SYN包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態。
第3次握手:客戶端和服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此時發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成3次握手。
完成3次握手,客戶端與服務器開始傳送數據。在上述過程中,還有一些概念。
未連接隊列:在3次握手協議中,服務器維護一個未連接隊列,該隊列為每個客戶端的SYN包(syn=j)開設一個條目,該條目表明服務器已收到SYN包,并向客戶發出確認,正在等待的客戶的確認包。這些條目所標識的鏈接在服務器處于Syn_RECV狀態,當服務器收到客戶的確認保濕,刪除該條目,服務器進入ESTABLISHED狀態。
Backlog參數:標識未連接隊列的最大容納數目。
SYN-ACK重傳次數:服務器發送完SYN_ACK包,如果未收到客戶確認包,服務器進行首次重傳,等待一段時間仍未收到客戶確認包,進行第二次沖床,如果重傳次數超過系統規定的最大重傳次數,系統將該連接信息從半連接隊列中刪除。注意,每次重傳等待的時間不一定相同。
半連接存活時間:是指半連接隊列的條目存活的最長時間,即服務從收到SYN包到確認這個報文無效的最長時間,該時間值是左右重傳請求包的最長等待時間總和。有時我們也成辦理按揭存活時間為Timeout時間、SYN_RECV存活時間。