基于TCP的半關閉
Linux的close函數(shù)不夠優(yōu)雅是因為在它之后不僅無法傳輸數(shù)據(jù),也不能接收數(shù)據(jù)。但TCP協(xié)議原本的設計不是這樣的。因此需要一個函數(shù)來僅斷開一個方向的流。
/*
* @params
* sock: 需要斷開的套接字描述符
* howto: 傳遞斷開方式信息。SHUT_RD:斷開輸入流,SHUT_WR:斷開輸出流,SHUT_RDWR:同時斷開I/O流。
*/
#include >sys/socket.h>
int shutdown(int sock, int howto); // 成功時返回0,失敗時返回-1
半關閉服務器與客戶端運行示例:
# gcc file_server.c -o fserver
# ./fserver 9190
Connected client
Message from client: Thanks you
# gcc file_client -o fclient
# ./fclient 127.0.0.1 9190
Connected
# cat reveive.dat
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
...
習題
- 解釋TCP中“流”的概念。UDP中能否形成流?請說明原因。
把兩臺主機通過套接字建立連接后進入可交換數(shù)據(jù)的狀態(tài)看作一種流。UDP沒有連接的概念,也就不是一種流協(xié)議。- Linux中的close函數(shù)或Windows中的closesocket函數(shù)屬于單方面斷開連接的方法,有可能帶來一些問題。什么是單方面斷開連接?什么情形下會出現(xiàn)問題?
單方面斷開連接就是某一方直接斷開I/O流。想象這種情況,A發(fā)送完了自己的數(shù)據(jù),于是單方面斷開連接,但B還有數(shù)據(jù)要發(fā)送,但A會直接丟棄后面的數(shù)據(jù)。當然,A可以發(fā)送完了自己的數(shù)據(jù)等待B發(fā)送完成,問題在于A不知道B何時能傳輸完畢,因此需要一個“可以關閉的信號”。這個信號如果是自定義的字符可能會出現(xiàn)在傳輸數(shù)據(jù)中,不如就將它確定為“EOF”,由shutdown函數(shù)來專門負責發(fā)送。- 什么是半關閉?針對輸出流執(zhí)行半關閉的主機處于何種狀態(tài)?半關閉會導致對方主機接收什么消息?
半關閉就是只關閉輸入流或輸出流。針對輸出流執(zhí)行半關閉的主機不能再發(fā)送數(shù)據(jù),但可以繼續(xù)接收數(shù)據(jù)。EOF。
我的問題
A端close以后對端B能發(fā)送數(shù)據(jù)嗎?
B可以發(fā)送,但A沒辦法接收了。
附錄
[1] Github