C語言setsockopt()函數(shù):設(shè)置socket狀態(tài)
頭文件:
#include <sys/types.h> #include <sys/socket.h>
定義函數(shù):
int setsockopt(int s, int level, int optname, const void * optval, ,socklen_toptlen);
函數(shù)說明:setsockopt()用來設(shè)置參數(shù)s 所指定的socket 狀態(tài). 參數(shù)level 代表欲設(shè)置的網(wǎng)絡(luò)層, 一般設(shè)成SOL_SOCKET 以存取socket 層. 參數(shù)optname 代表欲設(shè)置的選項, 有下列幾種數(shù)值:
SO_DEBUG 打開或關(guān)閉排錯模式
SO_REUSEADDR 允許在bind ()過程中本地地址可重復(fù)使用
SO_TYPE 返回socket 形態(tài).
SO_ERROR 返回socket 已發(fā)生的錯誤原因
SO_DONTROUTE 送出的數(shù)據(jù)包不要利用路由設(shè)備來傳輸.
SO_BROADCAST 使用廣播方式傳送
SO_SNDBUF 設(shè)置送出的暫存區(qū)大小
SO_RCVBUF 設(shè)置接收的暫存區(qū)大小
SO_KEEPALIVE 定期確定連線是否已終止.
SO_OOBINLINE 當(dāng)接收到OOB 數(shù)據(jù)時會馬上送至標準輸入設(shè)備
SO_LINGER 確保數(shù)據(jù)安全且可靠的傳送出去.
參數(shù) optval 代表欲設(shè)置的值, 參數(shù)optlen 則為optval 的長度.
返回值:成功則返回0, 若有錯誤則返回-1, 錯誤原因存于errno.
附加說明:
1、EBADF 參數(shù)s 并非合法的socket 處理代碼
2、ENOTSOCK 參數(shù)s 為一文件描述詞, 非socket
3、ENOPROTOOPT 參數(shù)optname 指定的選項不正確.
4、EFAULT 參數(shù)optval 指針指向無法存取的內(nèi)存空間.
C語言accept()函數(shù):接受socket連線
頭文件:
#include <sys/types.h> #include <sys/socket.h>
定義函數(shù):
int accept(int s, struct sockaddr * addr, int * addrlen);
函數(shù)說明:accept()用來接受參數(shù)s 的socket 連線. 參數(shù)s 的socket 必需先經(jīng)bind()、listen()函數(shù)處理過, 當(dāng)有連線進來時accept()會返回一個新的socket 處理代碼, 往后的數(shù)據(jù)傳送與讀取就是經(jīng)由新的socket處理, 而原來參數(shù)s 的socket 能繼續(xù)使用accept()來接受新的連線要求. 連線成功時, 參數(shù)addr 所指的結(jié)構(gòu)會被系統(tǒng)填入遠程主機的地址數(shù)據(jù), 參數(shù)addrlen 為scokaddr 的結(jié)構(gòu)長度. 關(guān)于機構(gòu)sockaddr 的定義請參考bind().accept()系統(tǒng)調(diào)用主要用在基于連接的套接字類型,比如SOCK_STREAM和SOCK_SEQPACKET。它提取出所監(jiān)聽套接字的等待連接隊列中第一個連接請求,創(chuàng)建一個新的套接字,并返回指向該套接字的文件描述符。新建立的套接字不在監(jiān)聽狀態(tài),原來所監(jiān)聽的套接字也不受該系統(tǒng)調(diào)用的影響。
備注:新建立的套接字準備發(fā)送send()和接收數(shù)據(jù)recv()。返回值:成功則返回新的socket 處理代碼, 失敗返回-1, 錯誤原因存于errno 中.
錯誤代碼:
1、EBADF 參數(shù)s 非合法socket 處理代碼.
2、EFAULT 參數(shù)addr 指針指向無法存取的內(nèi)存空間.
3、ENOTSOCK 參數(shù)s 為一文件描述詞, 非socket.
4、EOPNOTSUPP 指定的socket 并非SOCK_STREAM.
5、EPERM 防火墻拒絕此連線.
6、ENOBUFS 系統(tǒng)的緩沖內(nèi)存不足.
7、ENOMEM 核心內(nèi)存不足.
為了在套接字中有到來的連接時得到通知,可以使用select()或poll()。當(dāng)嘗試建立新連接時,系統(tǒng)發(fā)送一個可讀事件,然后調(diào)用accept()為該連接獲取套接字。另一種方法是,當(dāng)套接字中有連接到來時設(shè)定套接字發(fā)送SIGIO信號。
成功時,返回非負整數(shù),該整數(shù)是接收到套接字的描述符;出錯時,返回-1,相應(yīng)地設(shè)定全局變量errno。
Linux下,accept()把已等待的網(wǎng)絡(luò)錯誤傳給新建立的連接,當(dāng)作是accept()返回的錯誤。這于其他的BSD實現(xiàn)是不同的。為了可靠運行,應(yīng)該在accept()之后檢測協(xié)議已定義的一些網(wǎng)絡(luò)錯誤,并把這些錯誤當(dāng)作EAGAIN并重試。對于TCP/IP協(xié)議來說,主要有錯誤:ENETDOWN,EPROTO,ENOPROTOOPT,EHOSTDOWN,ENONET,EHOSTUNREACH,EOPNOTSUPP和ENETUNREACH。
C語言shutdown()函數(shù):終止socket通信
頭文件:
#include <sys/socket.h>
定義函數(shù):
int shutdown(int s, int how);
函數(shù)說明:shutdown()用來終止參數(shù)s 所指定的socket 連線. 參數(shù)s 是連線中的socket 處理代碼, 參數(shù)how有下列幾種情況:
返回值:成功則返回0, 失敗返回-1, 錯誤原因存于errno.
錯誤代碼:
1、EBADF 參數(shù)s 不是有效的socket 處理代碼
2、ENOTSOCK 參數(shù)s 為一文件描述詞, 非socket
3、ENOTCONN 參數(shù)s 指定的socket 并未連線
注意:
1>. 如果有多個進程共享一個套接字,close每被調(diào)用一次,計數(shù)減1,直到計數(shù)為0時,也就是所用進程都調(diào)用了close,套
接字將被釋放。
2>. 在多進程中如果一個進程中shutdown(sfd, SHUT_RDWR)后其它的進程將無法進行通信. 如果一個進程close(sfd)將不會
影響到其它進程. 得自己理解引用計數(shù)的用法了. 有Kernel編程知識的更好理解了.
============================================================
如果有五個進程使用該 socket id 則這個socket 描述符參考數(shù)則有五個,當(dāng)所有進程都close()了這樣參考數(shù)就等于0,該socket 就真的關(guān)閉釋放了。
如對本文有疑問,請?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會為你解答!! 點擊進入論壇