一、區別
- TCP 是面向連接的,UDP 是面向無連接的
- TCP提供可靠的服務。也就是說,通過TCP連接傳送的數據,無差錯,不丟失,不重復,且按序到達;UDP盡最大努力交付,即不保證可靠交付。Tcp通過校驗和,重傳控制,序號標識,滑動窗口、確認應答實現可靠傳輸。如丟包時的重發控制,還可以對次序亂掉的分包進行順序控制。
- TCP 保證數據正確性,UDP 可能丟包
- TCP 保證數據順序,UDP 不保證
- UDP具有較好的實時性,工作效率比TCP高,適用於對高速傳輸和實時性有較高的通信或廣播通信。
TCP
數據傳輸慢,UDP
數據傳送快
- 每一條TCP連接只能是點到點的;UDP支持一對一,一對多,多對一和多對多的交互通信。
- TCP對系統資源要求較多,UDP對系統資源要求較少。
- TCP 是面向字節流的,UDP 是基於數據報的。
二、頭部
TCP 20字節 圖片
- 狀態位。SYN 是發起一個鏈接,ACK 是回復,RST 是重新連接,FIN 是結束連接。因為 TCP 是面向連接的,因此需要雙方維護連接的狀態,這些狀態位的包會引起雙方的狀態變更
- 窗口大小,TCP 要做流量控制,需要通信雙方各聲明一個窗口,標識自己當前的處理能力。
UDP頭部 8字節
三、網絡編程
1. TCP
TCP編程的服務器端一般步驟是:
1、創建一個socket,用函數socket(); SOCKET SocketListen =socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
2、設置socket屬性,用函數setsockopt(); * 可選
3、綁定IP地址、端口等信息到socket上,用函數bind(); SOCKET_ERROR = bind(SocketListen,(const sockaddr*)&addr,sizeof(addr))
4、開啟監聽,用函數listen(); SOCKET_ERROR == listen(SocketListen,2)
5、接收客戶端上來的連接,用函數accept(); SOCKET SocketWaiter = accept(SocketListen, _Out_ struct sockaddr *addr _Inout_ int *addrlen);
6、收發數據,用函數send()和recv(),或者read()和write();
7、關閉網絡連接; closesocket(SocketListen);closesocket(SocketWaiter);
8、關閉監聽;
TCP編程的客戶端一般步驟是:
1、創建一個socket,用函數socket();
2、設置socket屬性,用函數setsockopt();* 可選
3、綁定IP地址、端口等信息到socket上,用函數bind();* 可選
4、設置要連接的對方的IP地址和端口等屬性;
5、連接服務器,用函數connect();
6、收發數據,用函數send()和recv(),或者read()和write();
7、關閉網絡連接;
int send( _In_ SOCKET s, //向哪個socket發送,accept返回的socket。 _In_ const char *buf, _In_ int len, _In_ int flags ); send(SocketClient,(const char *)&fh,sizeof(fh),0); recv(SocketClient,szbuf,sizeof(szbuf),0);
2. UDP
與之對應的UDP編程步驟要簡單許多,分別如下:
UDP編程的服務器端一般步驟是:
1、創建一個socket,用函數socket();
2、設置socket屬性,用函數setsockopt();* 可選
3、綁定IP地址、端口等信息到socket上,用函數bind();
4、循環接收數據,用函數recvfrom();
5、關閉網絡連接;
UDP編程的客戶端一般步驟是:
1、創建一個socket,用函數socket();
2、設置socket屬性,用函數setsockopt();* 可選
3、綁定IP地址、端口等信息到socket上,用函數bind();* 可選
4、設置對方的IP地址和端口等屬性;
5、發送數據,用函數sendto();
6、關閉網絡連接;
int recvfrom( _In_ SOCKET s, //綁定的socket _Out_ char *buf, _In_ int len, _In_ int flags, _Out_ struct sockaddr *from, //用來接收對方的 _Inout_opt_ int *fromlen ); int nres=recvfrom(pThis->m_socketListen,szBuf,sizeof(szBuf),0,(sockaddr*)&addrClient,&nSize);//0處標志位 sendto(m_socketListen,szBuffer,nSize,0,(const sockaddr*)&addr,sizeof(sockaddr_in))
注意區分recvfrom函數,由於是UDP非連接的所以在接受數據是要接受對方的ip等信息用於稍后發送信息,而TCP使用已連接的套接字維護連接信息。
SOCK_STREAM這種的特點是面向連接的,即每次收發數據之前必須通過connect建立連接,而SOCK_DGRAM這種是User Datagram Protocol協議的網絡通訊,它是無連接的,不可靠的。
兩者都是是OSI模型中傳輸層的協議
四、應用場景
UDP 的主要應用場景
- 需要資源少,網絡情況穩定的內網,或者對於丟包不敏感的應用,比如 DHCP 就是基於 UDP 協議的。
- 不需要一對一溝通,建立連接,而是可以廣播的應用。因為它不面向連接,所以可以做到一對多,承擔廣播或者多播的協議。
- 需要處理速度快,可以容忍丟包,但是即使網絡擁塞,也毫不退縮,一往無前的時候
基於 UDP 的幾個例子
- 直播。直播對實時性的要求比較高,寧可丟包,也不要卡頓的,所以很多直播應用都基於 UDP 實現了自己的視頻傳輸協議
- 實時游戲。游戲的特點也是實時性比較高,在這種情況下,采用自定義的可靠的 UDP 協議,自定義重傳策略,能夠把產生的延遲降到最低,減少網絡問題對游戲造成的影響
- 物聯網。一方面,物聯網領域中斷資源少,很可能知識個很小的嵌入式系統,而維護 TCP 協議的代價太大了;另一方面,物聯網對實時性的要求也特別高。比如 Google 旗下的 Nest 簡歷 Thread Group,推出了物聯網通信協議 Thread,就是基於 UDP 協議的
- 許多應用只支持UDP,如:多媒體數據流,不產生任何額外的數據,即使知道有破壞的包也不進行重發。
- 視頻聊天
TCP 的主要應用場景
- 適用於對數據傳輸可靠性要求比較高的場景,例如文本傳輸。
- 互聯網和企業網上客戶端應用,數據傳輸性能讓位於數據傳輸的完整性,可控制性和可靠性。
- 發消息的場景以及文件傳輸,要確保發送的消息不丟失
總結:
很明顯,當數據傳輸的性能必須讓位於數據傳輸的完整性、可控制性和可靠性時,TCP協議是當然的選擇。當強調傳輸性能而不是傳輸的完整性時,如:音頻和多媒體應用,UDP是最好的選擇。在數據傳輸時間很短,以至於此前的連接過程成為整個流量主體的情況下,UDP也是一個好的選擇,如:DNS交換。把SNMP建立在UDP上的部分原因是設計者認為當發生網絡阻塞時,UDP較低的開銷使其有更好的機會去傳送管理數據。TCP豐富的功能有時會導致不可預料的性能低下,但是我們相信在不遠的將來,TCP可靠的點對點連接將會用於絕大多數的網絡應用。
五、對應的協議
TCP
對應的協議
FTP:
定義了文件傳輸協議,使用21端口。Telnet:
一種用於遠程登陸的端口,使用23端口,用戶可以以自己的身份遠程連接到計算機上,可提供基於DOS模式下的通信服務。SMTP:
郵件傳送協議,用於發送郵件。服務器開放的是25號端口。POP3:
它是和SMTP對應,POP3用於接收郵件。POP3協議所用的是110端口。HTTP:
是從Web服務器傳輸超文本到本地瀏覽器的傳送協議。
UDP
對應的協議
DNS:
用於域名解析服務,將域名地址轉換為IP地址。DNS用的是53號端口。SNMP:
簡單網絡管理協議,使用161號端口,是用來管理網絡設備的。由於網絡設備很多,無連接的服務就體現出其優勢。TFTP(Trival File Transfer Protocal)
,簡單文件傳輸協議,該協議在熟知端口69上使用UDP
服務。