UNIX網絡編程-基本API介紹(二)

參考連接:http://www.cnblogs.com/riky/archive/2006/11/24/570713.aspxnode

一、getsockname和getpeername

getsockname函數獲取與套接口關聯的本地協議地址。算法

getpeername函數獲取與套接口關聯的遠程協議地址。編程

----------------------------------------------------------------------數組

#include <sys/socket.h>緩存

int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen);服務器

int getpeername(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen);網絡

返回:成功;-1 失敗。異步

----------------------------------------------------------------------socket

使用場合:函數

在不調用bind的TCP客戶,當connect成功返回後,getsockname返回分配給此鏈接的本地IP地址和本地端口號;

在以端口號爲0調用bind後,使用getsockname返回內核分配的本地端口號;

getsockname可用來獲取某套接口的地址族;

在捆綁了通配IP地址的TCP服務器上,當鏈接創建後,可使用getsockname得到分配給此鏈接的本地IP地址;

當一個服務器調用exec啓動後,他得到客戶身份的惟一途徑是調用getpeername函數。

二、select

----------------------------------------------------------------------

#include <sys/select.h>

#include <sys/time.h>

int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval *timeout);

返回:準備好描述字的正數目,0—超時,-1—出錯。

----------------------------------------------------------------------

2.1 結構timeval的定義:

struct timeval
{
    long tv_sec; /* seconds */
    long tv_usec; /* microseconds */
};

2.2 timeout取值的三種狀況:

    永遠等下去:僅在有一個描述字準備好I/O時才返回,設置timeout爲空指針;

    等待固定時間:在有一個描述字準備好I/O時返回,但不超過由timeout參數所指定的秒數和微秒數;

    根本不等待:檢查描述字後當即返回,將timeout中的秒數和微秒數都設置爲0。

    在等待過程當中,若進程捕獲了信號並從信號處理程序返回,等待通常被中斷,爲了可移植性,必須準備好select返回EINTR錯誤。

    timeout的值在返回時並不會被select修改(const標誌)。

2.3 readset、writeset、exceptset是內核測試讀、寫和異常條件所需的描述字。

    當前支持的異常條件有兩個:

        套接口帶外數據的到達;

        控制狀態信息的存在,可從一個已置爲分組方式的僞終端主端讀到。

    描述字集的使用:

        數據類型:fd_set;

        void FD_ZERO(fd_set *fdset);

        void FD_SET(int fd, fd_set *fdset);

        void FD_CLR(int fd, fd_set *fdset);

        void FD_ISSET(int fd, fd_set *fdset);

    參數maxfdp1指定被測試的描述字個數,它的值是要被測試的最大描述字加1。描述字0,1,2,…,maxfdp1-1都被測試。

    readset、writeset、exceptset是值-結果參數,select修改三者所指的描述字集。因此,每次調用select時,咱們都要將全部描述字集中關心的位置爲1。

2.4 套接口準備好讀的條件:

    套接口接收緩衝區中的數據字節數大於等於套接口接收緩衝區低潮限度的當前值。對這樣的套接口的讀操做將不阻塞並返回一個大於0的值(即準備好讀入的數據量)。能夠用套接口選項SO_RCVLOWAT來設置低潮限度,對於TCP和UDP,缺省值爲1;

    鏈接的讀這一半關閉(接收了FIN的TCP鏈接)。對這樣的套接口讀操做將不阻塞而且返回0(即文件結束符);

    套接口是一個監聽套接口且已完成的鏈接數爲非0;

    有一個套接口錯誤待處理。對這樣的套接口讀操做將不阻塞且返回一個錯誤,errno設置成明確的錯誤條件。這些待處理錯誤也能夠經過指定套接口選項SO_ERROR調用getsockopt來取得並清除。

2.5 套接口準備好寫的條件:

    套接口發送緩衝區中的可用字節數大於等於套接口發送緩衝區低潮限度的當前值,且或者(1)套接口已鏈接,或者(2)套接口不要求鏈接(如UDP套接口)。能夠用套接口選項SO_SNDLOWAT來設置此低潮限度,對於TCP和UDP,缺省值爲2048;

    鏈接的寫這一半關閉。對這樣的套接口寫將產生信號SIGPIPE;

    有一個套接口錯誤待處理。對這樣的套接口寫操做將不阻塞且返回一個錯誤,errno設置成明確的錯誤條件。這些待處理錯誤也能夠經過指定套接口選項SO_ERROR調用getsockopt來取得並清除。

    若是一個套接口存在帶外數據或者仍處於帶外標記,那它有異常條件待處理。

    一個套接口出錯時,它被select標記爲既可讀又可寫。

三、shutdown

----------------------------------------------------------------------

#include <sys/socket.h>

int shutdown(int sockfd, int howto);

返回:0 成功,-1 失敗。

----------------------------------------------------------------------

函數的行爲依賴於參數howto的值:

SHUT_RD:關閉鏈接的讀這一半,再也不接收套接口中的數據且留在套接口緩衝區中的數據都做廢。進程不能再對套接口任何讀函數。調用此函數後,由TCP套接口接收的任何數據都被確認,但數據自己被扔掉。

SHUT_WR:關閉鏈接的寫這一半,在TCP場合下,這稱爲半關閉。當前留在套接口發送緩衝區中的數據都被髮送,後跟正常的TCP鏈接終止序列。此半關閉無論套接口描述字的訪問計數是否大於0。進程不能再執行對套接口的任何寫函數。

SHUT_RDWR:鏈接的讀這一半和寫這一半都關閉。這等效於調用shutdown兩次:第一次調用時用SHUT_RD,第二次調用時用SHUT_WR。

四、pselect

----------------------------------------------------------------------

#include <sys/select.h>

#include <signal.h>

#include <time.h>

int pselect(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timespec *timeout, const sigset_t *sigmask);

返回:準備好描述字的個數,0—超時,-1—出錯。

----------------------------------------------------------------------

pselect是Posix.1g發明的。相對select的變化:

pselect使用結構timespec:

    struct timespec

    {

        time_t tv_sec; /* seconds */

        long tv_nsec; /* nanoseconds */

    };

新結構中的tv_nsec規定納秒數。

pselect增長了第六個參數:指向信號掩碼的指針。容許程序禁止遞交某些信號。

五、poll

----------------------------------------------------------------------

#include <poll.h>

int poll(struct pollfd *fdarray, unsigned long nfds, int timeout);

返回:準備好描述字的個數,0—超時,-1—出錯。

----------------------------------------------------------------------

5.1 pollfd結構

第一個參數是指向一個結構數組的第一個元素的指針,每一個數組元素都是一個pollfd結構:

struct pollfd

{

    int fd; /* descriptor to check */

    short events; /* events of interest on fd */

    short revents; /* events that occurred on fd */

};

要測試的條件由成員events規定,函數在相應的revents成員中返回描述字的狀態(一個描述字有兩個變量:一個爲調用值,一個爲結果)。

5.2 第二個參數指定數組中元素的個數。

5.3 第三個參數timeout。

指定函數返回前等待多長時間,單位是毫秒。可能值以下:

INFTIM,永遠等待;

0,當即返回,不阻塞;

>0,等待指定數目的毫秒數。

5.4 標誌的範圍:

常量

能做爲events的輸入嗎?

能做爲revents的結果嗎?

解釋

POLLIN

yes

yes

普通或優先級帶數據可讀

POLLRDNORM

yes

yes

普通數據可讀

POLLRDBAND

yes

yes

優先級帶數據可讀

POLLPRI

yes

 

高優先級數據可讀

POLLOUT

yes

yes

普通或優先級帶數據可寫

POLLWRNORM

yes

yes

普通數據可寫

POLLWRBAND

yes

yes

優先級帶數據可寫

POLLERR

 

yes

發生錯誤

POLLHUP

 

yes

發生掛起

POLLNVAL

 

yes

描述字不是一個打開的文件

 

圖表可分爲三部分:處理輸入的四個常值;處理輸出的三個常值;處理錯誤的三個值。

poll識別三個類別的數據:普通(normal)、優先級帶(priority band)、高優先級(high priority)。術語來自流的概念。

5.5 返回條件:

全部正規TCP數據和UDP數據都被認爲是普通數據;

TCP的帶外數據被認爲是優先級帶數據;

當TCP鏈接的讀這一半關閉時(如接收了一個FIN),這也認爲是普通數據,且後續的讀操做將返回0;

TCP鏈接存在錯誤既能夠認爲是普通數據,也能夠認爲是錯誤(POLLERR)。不管哪一種狀況,後續的讀操做將返回-1,並將errno置爲適當的值,這就處理了諸如接收到RST或超時等條件;

在監聽套接口上新鏈接的可用性既可認爲是普通數據,也能夠認爲是優先級帶數據,大多數實現都將其做爲普通數據考慮。

若是不關心某個特定的描述字,可將其pollfd結構的fd成員置爲一個負值,這樣就能夠忽略成員events,且返回時將成員revents的值置爲0。

poll沒有select存在的最大描述字數目問題。但可移植性select要好於poll。

六、getsockopt和setsockopt

----------------------------------------------------------------------

#include <sys/socket.h>

int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);

int setsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);

返回:0—OK-1—出錯。

----------------------------------------------------------------------

sockfd必須是一個打開的套接口描述字;level(級別)指定系統中解釋選項的代碼:普通套接口代碼或特定於協議的代碼);optval是一個指向變量的指針;此變量的大小由最後一個參數決定。

對於某些套接口選項,何時進行設置或獲取是有差異的。下面的套接口選項是由TCP已鏈接套接口從監聽套接口繼承來的:

SO_DEBUG;

SO_DONTROUTE;

SO_KEEPALIVE;

SO_LINGER;

SO_OOBINLINE;

SO_RCVBUF;

SO_SNDBUF。

若是想在三路握手完成時確保這些套接口選項中的某一個是給已鏈接套接口設置的,咱們必須先給監聽套接口設置此選項。

七、處理套接口的fcntl函數

----------------------------------------------------------------------

#include <fcntl.h>

int fcntl(int fd, int cmd, … /* arg */);

返回:依賴於參數cmd—成功,-1—失敗。

----------------------------------------------------------------------

函數fcntl提供了以下關於網絡編程的特性:

非阻塞I/O:經過用F_SETFL命令設置O_NONBLOCK文件狀態標誌來設置套接口爲非阻塞型。

信號驅動I/O:用F_SETFL命令來設置O_ASYNC文件狀態標誌,這致使在套接口狀態發生變化時內核生成信號SIGIO

F_SETOWN命令設置套接口屬主(進程ID或進程組ID),由它來接收信號SIGIOSIGURGSIGIO在設置套接口爲信號驅動I/O型時生成,SIGURG在新的帶外數據到達套接口時生成。

F_GETOWN命令返回套接口的當前屬主。

注意事項:

設置某個文件狀態標誌時,先取得當前標誌,與新標誌路邏輯或後再設置標誌。

信號SIGIOSIGURG與其餘信號不一樣之處在於,這兩個信號只有在已使用命令F_SETOWN給套接口指派了屬主後纔會生成。F_SETOWN命令的整參數arg既能夠是一個正整數,指明接收信號的進程ID,也能夠是一個負整數,它的絕對值是接收信號的進程組ID

當一個新的套接口由函數socket建立時,他沒有屬主,可是當一個新的套接口從一個監聽套接口建立時,套接口屬主便由已鏈接套接口從監聽套接口繼承而來。

八、gethostbyname

----------------------------------------------------------------------

#include <netdb.h>

struct hostent *gethostbyname(const char *hostname);

返回:非空指針—成功,空指針—出錯,同時設置h_errno

----------------------------------------------------------------------

函數返回的非空指針指向的結構以下:

struct hostent {

    char *h_name; /*規範主機名 */

    char **h_aliases; /* 別名列表 */

    int h_addrtype; /* AF_INET or AF_INET6 */

    int h_length; /* 地址長度 */

    char **h_addr_list; /* IPv4或IPv6地址結構列表 */

};

#define h_addr h_addr_list[0];

按照DNS的說法,gethostbyname執行一個對A記錄的查詢或對AAAA記錄的查詢,返回IPv4或IPv6地址。

h_addr的定義是爲了兼容,在新代碼中不該使用。

返回的h_name稱爲主機的規範(canonical)名字。當返回IPv6地址時,h_addrtype被設置爲AF_INET6,成員h_length被設置爲16。

gethostbyname的特殊之處在於:當發生錯誤時,他不設置errno,而是將全局整數h_errno設置爲定義在頭文件<netdb.h>中的下列常值中的一個:

HOST_NOT_FOUND;

TRY_AGAIN;

NO_RECOVERY;

NO_DATA(等同於NO_ADDRESS)。

有函數hstrerror(),它將h_errno的值做爲惟一的參數,返回一個指向相應錯誤說明的const char *型指針。

DNS小常識:

DNS中的條目稱爲資源記錄RR(resource record),僅有少數幾類RR會影響咱們的名字與地址轉換:

A:A記錄將主機名映射爲32位的IPv4地址;

AAAA:「四A」記錄將主機名映射爲128位的IPv6地址;

PTR:PTR記錄(稱爲「指針記錄」)將IP地址映射爲主機名;

MX:MX記錄指定一主機做爲某主機的「郵件交換器」。

CNAME:CNAME表明「canonical name(規範名字)」,其常見的用法是爲經常使用服務如ftp和www指派一個CNAME記錄。

21.gethostbyname2函數

 

#include <netdb.h>

struct hostent *gethostbyname2(const char *hostname, int family);

返回:非空指針—成功,空指針—出錯,同時設置h_errno

該函數容許指定地址族,其餘與gethostbyname類似。

九、gethostbyaddr

----------------------------------------------------------------------

#include <netdb.h>

struct hostent *gethostbyaddr(const char *addr, size_t len, int family);

返回:非空指針成功,空指針出錯,同時設置h_error

----------------------------------------------------------------------

函數根據一個二進制的IP地址並試圖找出相應於此地址的主機名,咱們關心的是規範主機名h_name。

參數addr不是char *類型,而是一個真正指向含有IPv4或IPv6地址的結構in_addr或in6_addr的指針;len是該結構的大小,對於IPv4是4,對於IPv6是16;family或爲AF_INET或爲AF_INET6。

按照DNS的說法,該函數查詢PTR記錄。

十、uname函數

----------------------------------------------------------------------

#include <sys/utsname.h>

int uname(struct utsname *name);

返回:非負值—成功,-1—失敗。

----------------------------------------------------------------------

返回當前主機的名字,存放在以下的結構裏:

#define UTS_NAMESIZE 16
#define UTS_NODESIZE 256

struct utsname
{
    char sysname[UTS_NAMESIZE];
    char nodename[UTS_NODESIZE];
    char release[UTS_NAMESIZE];
    char version[UTS_NAMESIZE];
    char machine[UTS_NAMESIZE];
};

 

該函數常常與gethostbyname一塊兒用來肯定本機的IP地址:先調用uname得到主機名字,而後調用gethostbyname獲得全部的IP地址。

得到本機IP地址的另外一個方法是ioctl的命令SIOCGIFCONF。

十一、gethostname函數

----------------------------------------------------------------------

#include <unistd.h>

int gethostname(char *name, size_t namelen);

返回:0—成功,-1—失敗。

----------------------------------------------------------------------

返回當前主機的名字。name是指向主機名存儲位置的指針,namelen是此數組的大小,若是有空間,主機名以空字符結束。

主機名的最大大小一般是頭文件<sys/param.h>定義的常值MAXHOSTNAMELEN。

十二、getservbyname函數

----------------------------------------------------------------------

#include <netdb.h>

struct servent *getservbyname(const char *servname, const char *protoname);

返回:非空指針成功,空指針失敗。

----------------------------------------------------------------------

函數返回以下結構的指針:

struct servent
{
    char *s_name;
    char **s_aliases;
    int s_port;
    char *s_proto;
};

服務名servname必須指定,若是還指定了協議(protoname爲非空指針),則結果表項必須有匹配的記錄。若是沒有指定協議名而服務支持多個協議,則返回哪一個端口是依賴於實現的。

結構中的端口號是以網絡字節序返回的,因此在將它存儲在套接口地址結構時,絕對不能調用htons。

1三、getservbyport函數

----------------------------------------------------------------------

#include <netdb.h>

struct servent *getservbyport(int port, const char *protname);

返回:非空指針成功,空指針出錯。

----------------------------------------------------------------------

port必須爲網絡字節序。例如:

sptr = getservbyport(htons(53), 「udp」);

1四、recv和send

----------------------------------------------------------------------

#include <sys/socket.h>

ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);

ssize_t send(int sockfd, void *buf, size_t nbytes, int flags);

返回:成功返回讀入或寫出的字節數,出錯返回-1

----------------------------------------------------------------------

前三個參數與read和write相同,參數flags的值或爲0,或由如下的一個或多個常值邏輯或構成:

flags 描述 recv send

MSG_DONTROUTE 不查路由表 y

MSG_DONTWAIT 本操做不阻塞 y y

MSG_OOB 發送或接收帶外數據 y y

MSG_PEEK 查看外來的消息 y

MSG_WAITALL 等待全部數據 y

下面說明每一個標誌的做用:

MSG_DONTROUTE:這個標誌告訴內核目的主機在直接鏈接的本地網絡上,不要查路由表。這是對提供這種特性的SO_DONTROUTE套接口選項的補充。該標誌能夠對單個輸出操做提供這種特性,而套接口選項則針對某個套接口上的全部輸出操做。

MSG_DONTWAIT:這個標誌將單個I/O操做設爲非阻塞方式,而不須要在套接口上打開非阻塞標誌,執行I/O操做,而後關閉阻塞標誌。

MSG_OOB:用send時,這個標誌指明發送的是帶外數據,用recv時,該標誌指明要讀的是帶外數據而不是通常數據。

MSG_PEEK:這個標誌可讓咱們查看可讀的數據,在recv或recvfrom後系統不會將這些數據丟棄。

MSG_WAITALL:由4.3BSD Reno引入,他告訴內核在沒有讀到請求的字節數以前不使讀操做返回。若是系統支持這個標誌,則能夠去掉readn函數。即便設定了該標誌 ,若是發生以下狀況:(1)捕獲了一個信號;(2)鏈接被終止;(3)在套接口上發生錯誤,這個函數返回的字節數仍會比請求的少。

1五、readv和writev

----------------------------------------------------------------------

#include <sys/uio.h>

ssize_t readv(int filedes, const struct iovec *iov, int iovcnt);

ssize_t writev(int filedes, const struct iovec *iov, int iovcnt);

返回:讀到或寫出的字節數,出錯返回-1

----------------------------------------------------------------------

readv和writev可讓咱們在一個函數調用中讀或寫多個緩衝區,這些操做被稱爲分散讀和集中寫。

iovec結構定義以下:

struct iovec
{
    void *iov_base; /* starting address of buffer */
    size_t iov_len; /* size of buffer */
};

在具體的實現中對iovec結構數組的元素個數有限制,4.3BSD最多容許1024個,而Solaris2.5上限是16。Posix.1g要求定義一個常值IOV_MAX,並且它的值不小於16。

readv和writev可用於任何描述字。writev是一個原子操做,能夠避免屢次寫引起的Nagle算法。

1六、readmsg和writemsg

----------------------------------------------------------------------

#include <sys/socket.h>

ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

ssize_t sendmsg(int sockfd, struct msghdr *msg, int flags);

返回:成功時爲讀入或寫出的字節數,出錯時爲-1

----------------------------------------------------------------------

這兩個函數是最通用的套接口I/O函數,能夠用recvmsg代替read、readv、recv和recvfrom,一樣,各類輸出函數均可以用sendmsg代替。

參數msghdr結構的定義以下:

struct msghdr 
{
    void *msg_name; /* protocol address */
    socklen_t msg_namelen; /* size of protocol address */
    struct iovec *msg_iov; /* scatter/gather array */
    size_t msg_iovlen; /* elements in msg_iov */
    void *msg_control; /* ancillary data; must be aligned for a cmsghdr structure */
    socklen_t msg_controllen; /* length of ancillary data */
    int msg_flags; /* flags returned by recvmsg() */
};

該結構源自4.3BSD Reno,也是Posix.1g中所說明的,有些系統仍使用一種老的msghdr結構,此種結構中沒有msg_flags成員,並且msg_control和msg_controllen成員分別被叫作msg_accrights和msg_accrightslen。老系統中支持的惟一一種輔助數據形式是文件描述字(稱爲訪問權限)的傳遞。

msg_name和msg_namelen成員用於未經鏈接的套接口,他們與recvfrom和sendto的第五和第六個參數相似:msg_name指向一個套接口地址結構,若是不須要指明協議地址,msg_name應被設置爲空指針,msg_namelen對sendmsg是一個值,而對recvmsg是一個值-結果參數。

msg_iov和msg_iovlen成員指明輸入或輸出的緩衝區數組。

msg_control和msg_controllen指明可選的輔助數據的位置和大小,msg_controllen對recvmsg是一個值-結果參數。

msg_flags只用於revmsg,調用recvmsg時,flags參數被拷貝到msg_flags成員,並且內核用這個值進行接收處理,接着它的值會根據recvmsg的結果而更新,sendmsg會忽略msg_flags成員,由於它在進行輸出處理時使用flags參數。

內核檢查的flags和返回的msg_flags以下表所示:

標誌 在send flags、

sendto flags、

sendmsg flags中檢查 在recv flags、

recvfrom flags、

recvmsg flags中檢查 在recvmsg msg_flags

中返回

MSG_DONTROUTE y

MSG_DONTWAIT y y

MSG_PEEK y

MSG_WAITALL y

MSG_EOR y y

MSG_OOB y y y

MSG_BCAST y

MSG_MCAST y

MSG_TRUNC y

MSG_CTRUNC y

前四個標誌只檢查不返回,下兩個標誌既檢查又返回,最後四個只返回。返回的六個標誌含義以下:

MSG_BCAST:當收到的數據報是一個鏈路層的廣播或其目的IP地址爲廣播地址時,將返回此標誌。

MSG_MCAST:當收到的數據報是鏈路層的多播時,將返回該標誌。

MSG_TRUNC:這個標誌在數據報被截斷時返回。

MSG_CTRUNC:這個標誌在輔助數據被截斷時返回。

MSG_EOR:若是返回的數據不是一個邏輯記錄的結尾,該標誌被清位,反之則置位。TCP不使用這個標誌,由於它是一種字節流協議。

MSG_OOB:這個標誌不是爲TCP的帶外數據返回的,它用於其餘協議族(譬如OSI協議等)。

具體的實現可能會在msg_flags中返回一些輸入的flags的標誌,因此咱們應該只檢查那些感興趣的標誌的值。

1七、socketpair函數

----------------------------------------------------------------------

#include <sys/socket.h>

int socketpair(int family, int type, int protocol, int sockfd[2]);

返回:成功返回0,出錯返回-1

----------------------------------------------------------------------

family必須爲AF_LOCAL,protocol必須爲0,type能夠是SOCK_STREAM或SOCK_DGRAM。新建立的兩個套接口描述字做爲sockfd[0]和sockfd[1]返回。

這兩個描述字相互鏈接,沒有名字,即沒有涉及隱式bind。

以SOCK_STREAM做爲type調用所獲得的結果稱爲流管道(stream pipe)。這與通常的UNIX管道相似,但流管道是全雙工的,兩個描述字都是可讀寫的。

1八、套接口ioctl函數

----------------------------------------------------------------------

#include <unistd.h>

int ioctl(int fd, int request, … /* void *arg */ );

返回:成功返回0,出錯返回-1

----------------------------------------------------------------------

第三個參數老是一個指針,但指針的類型依賴於request。

ioctl和網絡有關的請求可分爲以下6類:

類別 request 描述 數據類型

套接口 SIOCATMARK 在帶外標誌上嗎 int

SIOCSPGRP 設置套接口的進程ID或進程組ID int

SIOCGPGRP 獲取套接口的進程ID或進程組ID int

文件 FIONBIO 設置/清除非阻塞標誌 int

FIOASYNC 設置/清除異步I/O標誌 int

FIONREAD 獲取接收緩衝區中的字節數 int

FIOSETOWN 設置文件的進程ID或進程組ID int

FIOGETOWN 獲取文件的進程ID或進程組ID int

接口 SIOCGIFCONF 獲取全部接口的列表 struct ifconf

SIOCSIFADDR 設置接口地址 struct ifreq

SIOCGIFADDR 獲取接口地址 struct ifreq

SIOCSIFFLAGS 設置接口標誌 struct ifreq

SIOCGIFFLAGS 獲取接口標誌 struct ifreq

SIOCSIFDSTADDR 設置點到點地址 struct ifreq

SIOCGIFDSTADDR 獲取點到點地址 struct ifreq

SIOCGIFBRDADDR   獲取廣播地址 struct ifreq

SIOCSIFBRDADDR 設置廣播地址 struct ifreq

SIOCGIFNETMASK 獲取子網掩碼 struct ifreq

SIOCSIFNETMASK 設置子網掩碼 struct ifreq

SIOCGIFMETRIC 獲取接口的測度(metric) struct ifreq

SIOCSIFMETRIC 設置接口的測度(metric) struct ifreq

SIOCxxx (有不少,依賴於實現)

ARP SIOCSARP 建立/修改ARP項 struct arpreq

SIOCGARP 獲取ARP項 struct arpreq

SIOCDARP 刪除ARP項 struct arpreq

路由 SIOCADDRT 增長路徑 struct rtentry

SIOCDELRT 刪除路徑 struct rtentry

流 I_xxx

18.1 套接口操做

SIOCATMARK:若是套接口的讀指針當前在帶外標誌上,則經過第三個參數指向的整數返回一個非零值,不然返回零。Posix.1g用sockatmark代替了這種請求。

SIOCGPGRP:經過第三個參數指向的整數返回爲接收來自這個套接口的SIGIO或SIGURG信號而設置的進程ID或進程組ID。這和fcntl的F_GETOWN相同。

SIOCSPGRP:用第三個參數指向的整數設置進程ID或進程組ID以接收這個套接口的SIGIO或SIGURG信號。這和fcntl的F_SETOWN相同。

18.2 文件操做

FIONBIO:套接口的非阻塞標誌會根據第三個參數指向的值是否爲零而清除或設置。等價於fcntl的F_SETFL設置/清除O_NONBLOCK標誌。

FIOASYNC:根據第三個參數指向的值是否爲零決定清除或接收套接口上的異步I/O信號。等價於fcntl的F_SETFL設置和清除O_AYNC標誌。

FIONREAD:在第三個參數指向的整數中返回套接口接收緩衝區中當前的字節數。

FIOSETOWN:在套接口上等價於SIOCSPGRP。

FIOGETOWN:在套接口上等價於SIOCGPGRP。

18.3 接口配置

SIOCGIFCONF:從內核中獲取系統中配置的全部接口。它使用告終構ifconf,ifconf又使用了ifreq結構。

結構定義以下:

struct ifconf
{
    int ifc_len; /* size of buffer, value-result */

    union 
    {
        caddr_t ifcu_buf; /* input from user->kernel */
        struct ifreq *ifcu_req; /* return from kernel->user */
    }ifc_ifcu;
};

#define ifc_buf ifc_ifcu.ifcu_buf
#define ifc_req ifc_ifcu.ifcu_req
#define IFNAMSIZ 16

struct ifreq 
{
    char ifr_name[IFNAMSIZ];
    union 
    {
        struct sockaddr ifru_addr;
        struct sockaddr ifru_dstaddr;
        struct sockaddr ifru_broadaddr;
        short ifru_flags;
        int ifru_metric;
        caddr_t ifru_data;
    }ifr_ifru;
};

#define ifr_addr ifr_ifru.ifru_addr
#define ifr_dstaddr ifr_ifru.ifru_dstaddr
#define ifr_broadaddr ifr_ifru.broadaddr
#define ifr_flags ifr_ifru.ifru_flags
#define ifr_metric ifr_ifru.ifru_metric
#define ifr_data ifr_ifru.ifru_data

在調用ioctl以前分配一個緩衝區和一個ifconf結構,而後初始化後者,iotctl的第三個參數指向ifconf結構。

一個實現獲取全部接口的程序,可參見unpv12e:lib/get_ifi_info.c

18.4 接口操做

SIOCGIFCONF:從內核中獲取系統中配置的全部接口。

18.5 ARP高速緩存操做

18.6 路由表操做

相關文章
相關標籤/搜索