使用send()函數發送數據,系統如何知道數據發送成功


函數作用

我們知道,服務端中有一個接收緩存區,客戶端中有一個發送緩存區,同時每個TCP socket在內核中也都有一個發送緩沖區和一個接收緩沖區,

 

send()函數的作用就是將客戶端或服務端中的數據拷貝到SOCKET的發送緩存區中

 

recv()函數的作用就是將SOCKET的接收緩存區中數據拷貝到客戶端或服務端的接收緩存區中

 

綜上,send()函數和recv()函數只完成應用層到傳輸層的數據搬運,並不直接將數據傳送到數據的另一端去,真正完成數據的傳輸的是協議功能(TCP/UDP)

 

函數參數

ssize_t  send(int sockfd,  const void *buf,   size_t len,  int flags);

 

sockfd:創建的sockfd文件描述符,

buf:發送數據所在的數據區,

len:發送數據的長度,

flags:標志位默認設置為0

 

send()函數的返回值

 

1、成功執行時,返回發送的字節數。

 

2、失敗則返回SOCKET_ERROR

 

 

ssize_t recv ( int sockfd,  void *buf,   size_t len,   int flags);

 

recv()函數的返回值

1、成功執行時,返回接收到的字節數。

2、若另一端已關閉連接則返回0,這種關閉是對方主動且正常的關閉

3、失敗返回-1,errno被設為以下的某個值   

 

如何判斷數據是否發送成功?

通過send()函數的返回值,應用層只知道數據是否“拷貝”成功,另一端是否接收數據成功僅靠send()函數的返回值是判斷不了的,

 

對方是否接收數據成功發送端是判斷不了的,如果發送端需要知道接收端是否接收數據成功,需要接收端給發送端返回一個值來確定(應用層面確定數據發送成功)

 

系統底層確定數據是否發送成功(協議層面確定數據發送成功)

 

TCP協議會確保數據完整的發送出去,同時保證數據到達接收端的SOCKET接收緩存區

 

TCP數據報首部包含發送數據包的基本信息,比如數據長度

 

TCP協議的ACK確認機制

 

當SOCKET發送緩存區的大小為0的時候,也可以確定數據完全發送出去,buffer.size()==0

 

補充:

1、滑動窗口在SOCKET的緩存區里面,窗口的大小會根據接收端的處理情況動態變化(保證SOCKET的接收緩沖區不會溢出)

 

2、TCP 的SOCKET有接收緩存區和發送緩存區,而UDP的socket只有一個接收緩沖區,沒有發送緩沖區,從概念上來說就是只要有數據就發,不管對方是否可以正確接收,所以不緩沖,不需要發送緩沖區。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM