Linux網(wǎng)絡(luò)編程--6. 高級套接字函數(shù)
發(fā)布時(shí)間:2008-09-17 閱讀數(shù): 次 來源:網(wǎng)樂原科技
在前面的幾個(gè)部分里面,我們已經(jīng)學(xué)會(huì)了怎么樣從網(wǎng)絡(luò)上讀寫信息了.前面的一些函數(shù)(read,write)是網(wǎng)絡(luò)程序里面最基本的函數(shù).也是最原始的通信函數(shù).在這一章里面,我們一起來學(xué)習(xí)網(wǎng)絡(luò)通信的高級函數(shù).這一章我們學(xué)習(xí)另外幾個(gè)讀寫函數(shù).
6.1 recv和send
recv和send函數(shù)提供了和read和write差不多的功能.不過它們提供 了第四個(gè)參數(shù)來控制讀寫操作.
int recv(int sockfd,void *buf,int len,int flags)
int send(int sockfd,void *buf,int len,int flags)
前面的三個(gè)參數(shù)和read,write一樣,第四個(gè)參數(shù)可以是0或者是以下的組合
_______________________________________________________________
| MSG_DONTROUTE | 不查找路由表 |
| MSG_OOB | 接受或者發(fā)送帶外數(shù)據(jù) |
| MSG_PEEK | 查看數(shù)據(jù),并不從系統(tǒng)緩沖區(qū)移走數(shù)據(jù) |
| MSG_WAITALL | 等待所有數(shù)據(jù) |
|--------------------------------------------------------------|
MSG_DONTROUTE:是send函數(shù)使用的標(biāo)志.這個(gè)標(biāo)志告訴IP協(xié)議.目的主機(jī)在本地網(wǎng)絡(luò)上面,沒有必要查找路由表.這個(gè)標(biāo)志一般用網(wǎng)絡(luò)診斷和路由程序里面.
MSG_OOB:表示可以接收和發(fā)送帶外的數(shù)據(jù).關(guān)于帶外數(shù)據(jù)我們以后會(huì)解釋的.
MSG_PEEK:是recv函數(shù)的使用標(biāo)志,表示只是從系統(tǒng)緩沖區(qū)中讀取內(nèi)容,而不清楚系統(tǒng)緩沖區(qū)的內(nèi)容.這樣下次讀的時(shí)候,仍然是一樣的內(nèi)容.一般在有多個(gè)進(jìn)程讀寫數(shù)據(jù)時(shí)可以使用這個(gè)標(biāo)志.
MSG_WAITALL是recv函數(shù)的使用標(biāo)志,表示等到所有的信息到達(dá)時(shí)才返回.使用這個(gè)標(biāo)志的時(shí)候recv回一直阻塞,直到指定的條件滿足,或者是發(fā)生了錯(cuò)誤. 1)當(dāng)讀到了指定的字節(jié)時(shí),函數(shù)正常返回.返回值等于len 2)當(dāng)讀到了文件的結(jié)尾時(shí),函數(shù)正常返回.返回值小于len 3)當(dāng)操作發(fā)生錯(cuò)誤時(shí),返回-1,且設(shè)置錯(cuò)誤為相應(yīng)的錯(cuò)誤號(hào)(errno)
如果flags為0,則和read,write一樣的操作.還有其它的幾個(gè)選項(xiàng),不過我們實(shí)際上用的很少,可以查看 Linux Programmer's Manual得到詳細(xì)解釋.
6.2 recvfrom和sendto
這兩個(gè)函數(shù)一般用在非套接字的網(wǎng)絡(luò)程序當(dāng)中(UDP),我們已經(jīng)在前面學(xué)會(huì)了.
6.3 recvmsg和sendmsg
recvmsg和sendmsg可以實(shí)現(xiàn)前面所有的讀寫函數(shù)的功能.
int recvmsg(int sockfd,struct msghdr *msg,int flags)
int sendmsg(int sockfd,struct msghdr *msg,int flags)
struct msghdr
{
void *msg_name;
int msg_namelen;
struct iovec *msg_iov;
int msg_iovlen;
void *msg_control;
int msg_controllen;
int msg_flags;
}
struct iovec
{
void *iov_base; /* 緩沖區(qū)開始的地址 */
size_t iov_len; /* 緩沖區(qū)的長度 */
}
msg_name和 msg_namelen當(dāng)套接字是非面向連接時(shí)(UDP),它們存儲(chǔ)接收和發(fā)送方的地址信息.msg_name實(shí)際上是一個(gè)指向struct sockaddr的指針,msg_name是結(jié)構(gòu)的長度.當(dāng)套接字是面向連接時(shí),這兩個(gè)值應(yīng)設(shè)為NULL. msg_iov和msg_iovlen指出接受和發(fā)送的緩沖區(qū)內(nèi)容.msg_iov是一個(gè)結(jié)構(gòu)指針,msg_iovlen指出這個(gè)結(jié)構(gòu)數(shù)組的大小. msg_control和msg_controllen這兩個(gè)變量是用來接收和發(fā)送控制數(shù)據(jù)時(shí)的 msg_flags指定接受和發(fā)送的操作選項(xiàng).和recv,send的選項(xiàng)一樣
6.4 套接字的關(guān)閉
關(guān)閉套接字有兩個(gè)函數(shù)close和shutdown.用close時(shí)和我們關(guān)閉文件一樣.
6.5 shutdown
int shutdown(int sockfd,int howto)
TCP連接是雙向的(是可讀寫的),當(dāng)我們使用close時(shí),會(huì)把讀寫通道都關(guān)閉,有時(shí)侯我們希望只關(guān)閉一個(gè)方向,這個(gè)時(shí)候我們可以使用shutdown.針對不同的howto,系統(tǒng)回采取不同的關(guān)閉方式.
howto=0這個(gè)時(shí)候系統(tǒng)會(huì)關(guān)閉讀通道.但是可以繼續(xù)往接字描述符寫.
howto=1關(guān)閉寫通道,和上面相反,著時(shí)候就只可以讀了.
howto=2關(guān)閉讀寫通道,和close一樣 在多進(jìn)程程序里面,如果有幾個(gè)子進(jìn)程共享一個(gè)套接字時(shí),如果我們使用shutdown, 那么所有的子進(jìn)程都不能夠操作了,這個(gè)時(shí)候我們只能夠使用close來關(guān)閉子進(jìn)程的套接字描述符.