send與recv
socket的send和recv是同時支持TCP和UDP的胜臊。從這兩個函數(shù)的設計可以看出沙咏,協(xié)議簡單來說就是讀寫數(shù)據。
1.TCP情況下
socket的選項是SOCK_STREAM
。
send的返回值>0時,表示實際發(fā)送了多少字節(jié)罚舱。注意:只是copy到系統(tǒng)緩存里井辜,系統(tǒng)決定什么時候會發(fā)送這些數(shù)據。
send的返回值==0時管闷,這個在send空串時會發(fā)生粥脚,是正常的。
send的返回值<0時(只會等于-1吧)渐北,需要檢查errno阿逃,當errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN
時铭拧,連接正常赃蛛,可以稍后再試。其他的就是連接異常了搀菩。
recv的返回值>0時呕臂,表示實際接受到多少字節(jié)。
recv的返回值==0時肪跋,表示連接斷開歧蒋,也就是收到了FIN或者RST。
recv的返回值<0時州既,檢查errno谜洽,和send類似。
2.UDP情況下
socket的選項是SOCK_DGRAM
吴叶。
send的返回值>0時阐虚,返回值應該等于發(fā)送的數(shù)據長度。如果send的數(shù)據大于MTU蚌卤,會在IP層分片实束,到達目標機器后IP層重組。
send的返回值==0時逊彭,這個只在發(fā)送空串時出現(xiàn)咸灿。注意:真的會發(fā)送空數(shù)據的。
send的返回值<0時侮叮,檢查errno避矢,確定連接是否還正常。一般不會發(fā)生吧囊榜,UDP的send是直接發(fā)送出去的审胸。
recv的返回值>0時,收到一個完整的數(shù)據包锦聊。這個完整性是有IP層保證的歹嘹。
recv的返回值==0時,收到空包孔庭,這和TCP有很大不同尺上。
recv的返回值<0時材蛛,檢查errno,確定socket是否正常怎抛。
PS:UDP還有兩個函數(shù)sendto
和recvfrom
卑吭。客戶端在調用connect后马绝,才能用send
和recv
豆赏,服務器端只能用sendto
和recvfrom
。
3.TCP和UDP
UDP無連接富稻,無順序掷邦,自然不能代替TCP。
TCP是流式協(xié)議椭赋,需要應用層確認數(shù)據是否接受完整抚岗,也不能代替UDP。
應用要同時支持兩種協(xié)議哪怔,得在上層做包裝宣蔚。有個KCP,使用UDP模擬TCP认境。