send & recv 函數(shù)
#include <sys/socket.h>
/*
* @params
* sockfd: 表示與數(shù)據(jù)傳輸對象的連接的套接字文件描述符
* buf: 保存待傳輸數(shù)據(jù)的緩沖地址值
* nbytes: 待傳輸?shù)淖止?jié)數(shù)
* flags: 傳輸數(shù)據(jù)時指定的可選項信息
*/
ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags); // 成功時返回發(fā)送的字節(jié)數(shù),失敗時返回-1
/*
* @params
* sockfd: 表示與數(shù)據(jù)接收對象的連接的套接字文件描述符
* buf: 保存接收數(shù)據(jù)的緩沖地址值
* nbytes: 可接收的最大字節(jié)數(shù)
* flags: 接收數(shù)據(jù)時指定的可選項信息
*/
ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags); // 成功時返回發(fā)送的字節(jié)數(shù)(收到EOF時返回0),失敗時返回-1
| 可選項 | 含義 | send | recv | 示例 |
|---|---|---|---|---|
| MSG_OOB | 傳輸一個字符的帶外數(shù)據(jù) | * | * | oob_recv.c和oob_send.c |
| MSG_PEEK | 驗證輸入緩沖中是否存在數(shù)據(jù) | * | peek_recv.c和peek_send.c | |
| MSG_DONTROUTE | 數(shù)據(jù)傳輸過程中不參照路由表,在本地網(wǎng)絡中尋找目的地 | * | ||
| MSG_DONTWAIT | 調用I/O函數(shù)時不阻塞 | * | * | |
| MSG_WAITALL | 直到接收全部請求的字節(jié)數(shù)再返回 | * |
# gcc oob_recv.c -o oobrecv
# ./oobrecv 9190
123
Urgent message: 4
567
Urgent message: 0
89
# gcc oob_send.c -o oobsend
# ./oobsend 127.0.0.1 9190
Connected
# gcc peek_recv.c -o peekrecv
# ./peekrecv 9190
Buffering 3 bytes: 123
Reading 3 bytes: 123
# gcc peek_send.c -o peeksend
# ./peeksend 127.0.0.1 9190
Connected
readv & writev 函數(shù)
#include <sys/uio.h>
struct iovec {
void *iov_base; // 緩沖地址
size_t iov_len; // 緩沖大小
}
/*
* @params
* filedes: 表示數(shù)據(jù)傳輸對象的套接字文件描述符/文件或標準輸出描述符
* iov: iovec結構體數(shù)組的地址值,結構體iovec中包含待發(fā)送數(shù)據(jù)的位置和大小信息
* iovcnt: 第二個參數(shù)的數(shù)組長度
*/
ssize_t writev(int filedes, const struct iovec * iov, int iovcnt); // 成功時返回發(fā)送的字節(jié)數(shù),失敗時返回-1
/*
* @params
* filedes: 接收數(shù)據(jù)的套接字文件描述符/文件或標準輸出描述符
* iov: iovec結構體數(shù)組的地址值,結構體iovec中包含保存數(shù)據(jù)的位置和大小信息
* iovcnt: 第二個參數(shù)的數(shù)組長度
*/
ssize_t readv(int filedes, const struct iovec * iov, int iovcnt); // 成功時返回發(fā)送的字節(jié)數(shù),失敗時返回-1
# gcc writev.c -o wv
# ./wv
ABC1234
Write bytes: 7
# gcc readv.c -o rv
# ./rv
I like reading.
First message: I lik
Second message: e reading.
習題
- 下列關于MSG_OOB可選項的說法錯誤的是?
a. MSG_OOB指傳輸Out-of-band數(shù)據(jù),是通過其他路徑高速傳輸數(shù)據(jù)。
b. MSG_OOB指通過其他路徑高速傳輸數(shù)據(jù),因此,TCP中設置該選項的數(shù)據(jù)先到達對方主機。
c. 設置MSG_OOB使數(shù)據(jù)先到達對方主機后,以普通數(shù)據(jù)的形式和順序讀取。也就是說,只是提高了傳輸速度,接收方無法識別這一點。
d. MSG_OOB無法脫離TCP的默認數(shù)據(jù)傳輸方式。即使設置了MSG_OOB,也會保持原有傳輸順序。該選項只用于要求接收方緊急處理。
abc。- 利用readv&writev函數(shù)首發(fā)數(shù)據(jù)有何優(yōu)點?分別從函數(shù)調用次數(shù)和I/O緩沖的角度看給出說明。
相比于分次讀進來拷貝到不同數(shù)組,這個函數(shù)只需要調用一次。如果關閉了NAGLE算法,用這個函數(shù)可以將數(shù)據(jù)打包發(fā)送節(jié)省帶寬。- 通過recv函數(shù)驗證輸入緩沖是否存在數(shù)據(jù)時(確認后立即返回),如何設置recv函數(shù)最后一個參數(shù)中的可選項?分別說明各可選項的含義。
MSG_PEEK|MSG_DONTWAIT。驗證輸入緩沖區(qū)是否存在數(shù)據(jù)|非阻塞。
附錄
[1] Github