本文所有函式皆是為實現 tcp之簡單回傳(二) 系列所封裝的函式;
所有函式皆用c語言實現。函式以及注釋如下:
標頭檔案:
//.h#ifndef sysutil_h
#define sysutil_h#include
#include
void nano_sleep(double val); //
實現定時作用
ssize_t readn(int fd, void *buf, size_t count);//
讀取真實資料
ssize_t writen(int fd, const
void *buf, size_t count);//
寫所讀來的資料
ssize_t readline(int fd, void *usrbuf, size_t maxlen);//
讀資料(解決粘包問題)
ssize_t readline_slow(int fd, void *usrbuf, size_t maxlen);//
讀資料--->效率低下
void send_int32(int sockfd, int32_t val);//
傳送乙個int
int32_t recv_int32(int sockfd); //
接收乙個int 為後來的readn讀入精準的資料做準備
#endif
具體實現:
/.c#include
"sysutil.h
"#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
in.h>#include
#define err_exit(m) \
dowhile(0)//
睡眠時間
void nano_sleep(double
val)
while(ret == -1 && errno ==eintr);//
若是被中斷訊號打斷,則繼續執行sleep }//
告訴server,本次傳送資料的真實長度val
void send_int32(int
sockfd, int32_t val)
//接收乙個int型資料,以確保精確接收
int32_t recv_int32(int
sockfd)
//server讀取資料
ssize_t readn(int fd, void *buf, size_t count)
else
if( nread == 0
)
nleft = nleft - nread;//
剩餘字元數
pbuf = pbuf + nread;//
下次的偏移位置
}
return (count-nleft) ;//
attentin 兩個條件退出迴圈}//
client向server寫資料
ssize_t writen(int fd, const
void*buf, size_t count)
nleft = nleft - nwrite;//
剩餘位元組流
pbuf = pbuf + nwrite;//
偏移位置
}
return
count;}//
預覽核心緩衝區資料
ssize_t recv_peek(int fd, void *usrbuf, size_t maxlen)
while(nread == -1 && errno ==eintr);
return
nread;
}ssize_t readline(
int fd, void *usrbuf, size_t maxlen)
}//不存在'\n'
if( readn(fd, bufp, nread) !=nread)
err_exit(
"readn");
bufp +=nread;
count +=nread;
nleft -=nread;
}*bufp = 0
;
return
count;}//
按字元讀取--->由於每讀取乙個字元就產生一次系統呼叫,故效率較低
ssize_t readline_slow(int fd, void *usrbuf, size_t maxlen)
else
if(0 ==nread )
break; //
eof
*bufp = ch;//
將讀取的字元存進buf
bufp++;//
向前移動
nleft --;//
剩餘位元組數--
if(ch == '
\n')//
如果該字元為\n。本次讀取完成
break
; }
*bufp ='
\0';//
return (maxlen- nleft -1);//
最大長度 -剩餘的字元 - '\0'
}
readn的返回值:
1.小於0,出錯
2.等於0,對方關閉
3.大於0,但是小於count,對方關閉
4.count,代表讀滿count個位元組
對於readn函式中的read函式返回值為0 的問題,在這裡我們給解釋一下:
該readn函式用於tcp連線之後讀取buffer中的資料問題,因此會涉及到監聽函式select、poll、epool及其返回值。為了敘述方便,假設伺服器為s,客戶端為c;1、當客戶端c關閉寫端時,就會向伺服器s傳送(write)乙個長度為0的資料;
2、伺服器的 監聽函式 監聽到客戶端c有訊息推送過來,這時就會呼叫read函式,通過read函式的返回值,就得知客戶端c的寫端已關閉,因此為eof;
eof總結:
1、客戶端c寫端關閉;
2、伺服器監聽到客戶端c有訊息傳送過來;
3、通過read函式的返回值得知,nread=0.
tcp 資料封裝
資料封裝 當主機跨越 網路向其他裝置傳輸資料時,就要進行資料封裝,就是在 osi模型的每一層加上協議資訊。每一層只與接受裝置上相應的對等層進行通訊。為了實現通訊並交換資訊,每一層都使用協議資料單元 protocol data units,pdu 在模型中的每一層,這些含有控制資訊的 pdu被附加到資...
TCP之send函式研究
tcp協議本身是可靠的,並不等於應用程式用tcp傳送資料就一定是可靠的.不管是否阻塞,send傳送的大小,並不代表對端recv到多少的資料.在阻塞模式下,send函式的過程是將應用程式請求傳送的資料拷貝到傳送快取中傳送並得到確認後再返回.但由於傳送快取的存在,表現為 如果傳送快取大小比請求傳送的大小...
TCP之send函式研究
tcp協議本身是可靠的,並不等於應用程式用tcp傳送資料就一定是可靠的.不管是否阻塞,send傳送的大小,並不代表對端recv到多少的資料.在阻塞模式下,send函式的過程是將應用程式請求傳送的資料拷貝到傳送快取中傳送並得到確認後再返回.但由於傳送快取的存在,表現為 如果傳送快取大小比請求傳送的大小...