一個套接字描述符和一個文件描述符很相似
當套接字建立好了以后,可以用read 和 write 函數像操作文件描述符一樣操作套接字描述符。
而且還可以用fork函數建立更多的子進程,並且把套接字秒速符傳給子進程們進行read write!
除了read,write 以外還有6個特殊的讀寫函數!
寫:
#include<sys/socket.h>ssize_t send(int sockfd,const void* buf,size_t nbytes,int flags);
詳解:
前三個參數和write函數差不多,但是第四個參數就指示了send 的傳輸數據的方式:
MSG_CONFIRM 提供鏈路層反饋以保持地址映射有效
MSG_DONTROUTE 勿將數據包路由出本地網絡
MSG_DONTWAIT 允許非阻塞行為 - -
MSG_EOF 標記記錄結束
MSG_MORE 允許延遲並寫更多數據
MSG_NOSIGNAL 在無連接的套接字不產生信號SIGPIPE
MSG_OOB 允許發送帶外數據
對於報文數據發送,假如報文過長會導致錯誤。
對於字節流,則會阻塞到數據發送完成。
ssize_t sendt(int sockfd,const void *buf,size_t nbyte,int flags,
const struct sockaddr* destaddr,socklen_t destlen);
和send差不多,但是多了兩個參數,地址結構和地址長度!所以發送時可以不用連接直接往這個地址發送!
ssize_t sendmsg(int sockfd,const struct msghdr *msg,int flags);
這個也和send 差不多就是多了一個msghdr 數據結構,可以指定一個msghdr來多重緩沖區傳送數據。
struct msghdr{
void *msg_name;
socklen_t msg_namelen;
int msg_iovlen;
void *msg_control
socklen_t msg_controllen;
int msg_flags;
...}
讀:
#include<sys/socket.h>
ssize_t recv(int sockfd,void *buf,size_t mbytes,int flags);
讀除了read 以外還有recv!recv和read極為相似只不過有一點不同的是。
recv 可以指定標識符來控制如何接受數據。
MSG_CMSG_CLOEXEC
MSG_DONTWAIT 不阻塞的操作
MSG_ERRQUEUE 接受錯誤信息作為輔助數據
MSG_OOB 獲取帶外數據
MSG_PEEK 返回數據包內容而已不拿走
MSG_TRUNC 返回數據包實際長度即使被截斷
MSG_WAITALL 等到所有數據可用
有幾個點需要注意:
當用MSG_PEEK的時候僅僅是查看不是取走,再次使用read的時候還是剛剛的數據。
對於數據量少於預期而言,MSG_WAITALL可以讓避免等待,讓數據全部返回后就返回函數值。
ssize_t recvfrom(int sockfd,void *buf,size_t len,int flags
struct sockaddr addr,socklen_t addrlen);
如果有興趣定位數據發送者就使用這個。
ssize_t recvmsg(int sock,struct msghdr *msg,int flags);
如果想讓接受的數據輸入多個緩沖區就可以指定這個。flags 則指定標識符來指定接受數據的行為!
MSG_CTRUNC 控制數據被截斷
MSG_EOR 接收記錄結束符
MSG_ERRQUEUE 接受錯誤信息作為輔助數據
MSG_OOB 接受帶外數據
MSG_TRUNC 一般數據被截斷