1. 基本套接字函數
(1)socket函數原型算法
socket(創建一個socket文件描述符)服務器
所需頭文件網絡
#include <sys/types.h> dom
#include <sys/socket.h>socket
函數說明函數
創建一個socket文件描述符性能
函數原型大數據
int socket(int domain, int type, int protocol)調試
函數傳入值接口
domain
AF_INET:IPv4協議
AF_INET6:IPv6協議
AF_LOCAL:Unix域協議
AF_ROUTE:路由套接口
AF_KEY:密鑰套接口
type
SOCKET_STREAM:雙向可靠數據流,對應TCP
SOCKET_DGRAM:雙向不可靠數據報,對應UDP
SOCKET_RAW:提供傳輸層如下的協議,能夠訪問內部網絡接口,例如接收和發送ICMP報文
protocol
type爲SOCKET_RAW時須要設置此值說明協議類型,其餘類型設置爲0便可
函數返回值
成功:socket文件描述符
失敗:-1,失敗緣由存於error中
表18-1列出了當進行socket調用時,中協議簇(domain)與類型(type)可能產生的組合。
表18-1 socket中協議簇(domain)與類型(type)組合表
AF_INET
AF_INET6
AF_LOCAL
AF_ROUTE
AF_KEY
SOCK_STREAM
TCP
TCP
Yes
SOCK_DGRAM
UDP
UDP
Yes
SOCK_RAW
IPv4
IPv6
Yes
Yes
(2)bind函數原型
bind(將一個本地協議地址與socket文件描述符聯繫起來)
所需頭文件
#include <sys/types.h>
#include <sys/socket.h>
函數說明
將一個協議地址與socket文件描述符聯繫起來
函數原型
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
函數傳入值
sockfd
socket文件描述符
addr
my_addr指向sockaddr結構,該結構中包含IP地址和端口等信息
addrlen
sockaddr結構的大小,可設置爲sizeof(struct sockaddr)
函數返回值
成功:0
失敗:-1,失敗緣由存於error中
利用bind函數綁定地址時,能夠指定IP地址和端口號,也能夠指定其中之一,甚至一個也不指定。可使用通配地址INADDR_ANY(爲宏定義,其值等於0),它通知內核選擇IP地址。表18-2列出了設置socket地址結構的幾種方式,但在實際中,綁定的端口號都須要指定。
表18-2 設置socket地址結構的幾種方式
進程指定
說 明
IP地址
端口
通配地址INADDR_ANY
0
內核自動選擇IP地址和端口號
通配地址INADDR_ANY
非0
內核自動選擇IP地址,進程指定端口號
本地IP地址
0
進程指定IP地址,內核自動選擇端口號
本地IP地址
非0
進程指定IP地址和端口號
(3)listen函數原型
listen (等待鏈接)
所需頭文件
#include <sys/types.h>
#include <sys/socket.h>
函數說明
等待鏈接
函數原型
int listen(int sockfd, int backlog)
函數傳入值
sockfd
監聽socket文件描述符
backlog
套接字排隊的最大鏈接個數
函數返回值
成功:0
失敗:-1,失敗緣由存於error中
特別說明
對於監聽socket文件描述符sockfd,內核要維護兩個隊列,分別爲未完成鏈接隊列和已完成鏈接隊列,這兩個隊列之和不超過backlog
(4)connect函數原型
connect(創建socket鏈接)
所需頭文件
#include <sys/types.h>
#include <sys/socket.h>
函數說明
創建socket鏈接
函數原型
int connect(int sockfd, const struct sockaddr *serv_addr,
socklen_t addrlen)
函數傳入值
sockfd
socket文件描述符
serv_addr
鏈接的網絡地址和端口
addrlen
sockaddr結構的大小,可設置爲sizeof(struct sockaddr)
函數返回值
成功:0
失敗:-1,失敗緣由存於error中
附加說明
函數connect激發TCP的三路握手過程,出錯返回有如下幾種狀況:
① 若是客戶沒有收到SYN分節的響應(總共75秒,這之間可能重發了若干次SYN),則返回ETIMEDOUT
② 若是對客戶的SYN的響應是RST,則代表該服務器主機在指定的端口上沒有進程在等待與之相連,函數返回錯誤ECONNREFUSED
③ 若是客戶發出的SYN在中間路由器上引起一個目的地不可達的ICMP錯誤,內核返回EHOSTUNREACH或ENETUNREACH錯誤(即ICMP錯誤)給進程
(5)accept函數原型
accept(接受socket鏈接)
所需頭文件
#include <sys/types.h>
#include <sys/socket.h>
函數說明
接受socket鏈接,返回一個新的socket文件描述符,原socket文件描述符仍爲listen函數所用,而新的socket文件描述符用來處理鏈接的讀寫操做
函數原型
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
函數傳入參數
sockfd: socket文件描述符
addrlen:addr的大小,可設置爲sizeof(struct sockaddr)
函數傳出參數
addr:填入遠程主機的地址數據
函數返回值
成功:實際讀取字節數
失敗:-1,錯誤代碼存放在error中
附加說明
① accept函數由TCP服務器調用,爲阻塞函數,從已完成鏈接的隊列中返回一個鏈接;若是該對列爲空,則進程進入阻塞等待
② 函數返回的套接字爲已鏈接套接字,而監聽套接字仍爲listen函數所用
(6)close函數原型
close (關閉鏈接的socket文件描述符)
所需頭文件
#include <unistd.h>
函數說明
關閉鏈接的socket文件描述符
函數原型
int close(int sockfd)
函數傳入值
sockfd:socket文件描述符
函數返回值
成功:0
失敗:-1,失敗緣由存於error中
附加說明
① close函數默認功能是將套接字置爲「已關閉」標記,並當即返回給進程,這個套接字不能再爲該進程所用
② 正常狀況下,close將引起四個分節終止序列,但在終止前將發送已排隊的數據
③ 若是套接字描述符訪問計數在調用close後大於0(多個進程共享同一個套接字的狀況下),則不會引起TCP終止序列(即不會發送FIN分節)
(7)shutdown函數原型
shutdown(終止socket通訊)
所需頭文件
#include <sys/socket.h>
函數說明
終止socket通訊
函數原型
int shutdown(int s, int how)
函數傳入值
s
socket文件描述符
how
0(SHUT_RD):關閉socket鏈接的讀這一半,再也不接收套接字中的數據且現留在收緩衝區的數據做廢
1(SHUT_WR):關閉socket鏈接的寫這一半(半關閉),但留在套接字發送緩衝區中的數據都會被髮送,後跟TCP鏈接終止序列,無論訪問計數是否大於0,此後將不能再執行對套接字的任何寫操做
2(SHUT_RDWR):socket鏈接的讀、寫都關閉
函數返回值
成功:0
失敗:-1,失敗緣由存於error中
(8)read函數原型
read(從打開的socket文件流中讀取數據)
所需頭文件
#include <unistd.h>
函數說明
從打開的socket文件流中讀取數據,這裏僅說明此函數應用於socket的狀況
函數原型
ssize_t read(int fd, void *buf ,size_t count)
函數傳入參數
fd: socket文件描述符
count:最大讀取字節數
函數傳出參數
buf:讀取數據的首地址
函數返回值
成功:實際讀取字節數
失敗:-1,錯誤代碼存放在error中
附加說明
調用函數read從socket文件流中讀取數據時,有以下幾種狀況:
① 套接字接收緩衝區接收數據,返回接收到的字節數
② TCP協議收到FIN數據,返回0
③ TCP協議收到RST數據,返回-1,同時errno設置爲ECONNRESET
④ 進程阻塞過程當中接收到信號,返回-1,同時errno設置爲EINTR
(9)write函數原型
write(向socket文件流中寫入數據)
所需頭文件
#include <unistd.h>
函數說明
向socket文件流中寫入數據,這裏僅說明此函數應用於socket的狀況
函數原型
ssize_t write (int fd,const void *buf,size_t count)
函數傳入參數
fd: socket文件描述符
buf:寫入數據的首地址
count:最大寫入字節數
函數返回值
成功:實際寫入的字節數
失敗:-1,錯誤代碼存放在error中
附加說明
調用函數write向socket文件流寫數據時,有以下幾種狀況:
① 套接字發送緩衝區有足夠空間,返回發送的字節數
② TCP協議接收到RST數據,返回-1,同時errno設置爲ECONNRESET
③ 進程阻塞過程當中接收到信號,返回-1,同時errno設置爲EINTR
2. 高級套接字函數
recv和send函數提供了和read和write差很少的功能。不過它們提供了第四個參數來控制讀寫操做。
(1) send函數原型
send(經過socket文件描述符發送數據到對方)
所需頭文件
#include <sys/types.h>
#include <sys/socket.h>
函數說明
經過socket文件描述符發送數據到對方
函數原型
ssize_t send(int s, const void *buf, size_t len, int flags)
函數傳入值
s
socket文件描述符
buf
發送數據的首地址
len
發送數據的長度
flags
0:此時功能同write,flags還能夠設爲如下標誌的組合
MSG_OOB:發送帶外數據
MSG_DONTROUTE:告訴IP協議,目的主機在本地網絡,沒有必要查找路由表
MSG_DONTWAIT:設置爲非阻塞操做
MSG_NOSIGNAL:表示發送動做不肯被SIGPIPE信號中斷
函數返回值
成功:實際發送的字節數
失敗:-1,失敗緣由存於error中
(2) recv函數原型
recv(經過socket文件描述符從對方接收數據)
所需頭文件
#include <sys/types.h>
#include <sys/socket.h>
函數說明
經過socket文件描述符從對方接收數據
函數原型
ssize_t recv(int s, void *buf, size_t len, int flags)
函數傳入值
s
socket文件描述符
len
可接收數據的最大長度
flags
0:此時功能同read,flags還能夠設爲如下標誌的組合
MSG_OOB:接收帶外數據
MSG_PEEK:查看數據標誌,返回的數據並不在系統中刪除,若是再次調用recv函數會返回相同的數據內容
MSG_DONTWAIT:設置爲非阻塞操做
MSG_WAITALL:強迫接收到len大小的數據後才返回,除非有錯誤或有信號產生
函數傳出值
buf
接收數據的首地址
函數返回值
成功:實際發送的字節數
失敗:-1,失敗緣由存於error中
3. 套接字屬性控制函數
系統提供getsockopt、setsockopt兩函數獲取和修改套接字結構中一些屬性,經過修改這些屬性,能夠調整套接字的性能,進而調整應用程序的性能。
(1) getsockopt函數原型
getsockopt(獲取套接字的屬性)
所需頭文件
#include <sys/types.h>
#include <sys/socket.h>
函數說明
獲取套接字的屬性
函數原型
int getsockopt(int s, int level, int optname,
void *optval, socklen_t *optlen)
函數傳入值
s
socket文件描述符
level
SOL_SOCKET:通用套接字選項
IPPROTO_IP:IP選項
IPPROTO_TCP:TCP選項
optname
訪問的選項名,具體見表18-3
optlen
optval的長度
函數傳出值
optval
取得的屬性值
函數返回值
成功:0
失敗:-1,失敗緣由存於error中
表18-3 套接字屬性表
level(級別)
optname(選項名
說明
數據類型
SOL_SOCKET
SO_BROADCAST
容許發送廣播數據
int
SO_DEBUG
容許調試
int
SO_DONTROUTE
不查找路由
int
SO_ERROR
得到套接字錯誤
int
SO_KEEPALIVE
保持鏈接
int
SO_LINGER
延遲關閉鏈接
struct linger
SO_OOBINLINE
帶外數據放入正常數據流
int
SO_RCVBUF
接收緩衝區大小
int
SO_SNDBUF
發送緩衝區大小
int
SO_RCVLOWAT
接收緩衝區下限
int
SO_SNDLOWAT
發送緩衝區下限
int
SO_RCVTIMEO
接收超時
struct timeval
SO_SNDTIMEO
發送超時
struct timeval
SO_REUSERADDR
容許重用本地地址和端口
int
SO_TYPE
得到套接字類型
int
SO_BSDCOMPAT
與BSD系統兼容
int
IPPROTO_IP
IP_HDRINCL
在數據包中包含IP首部
int
IP_OPTINOS
IP首部選項
int
IP_TOS
服務類型
int
IP_TTL
生存時間
int
IPPRO_TCP
TCP_MAXSEG
TCP最大數據段的大小
int
CP_NODELAY
不使用Nagle算法
int
(2)setsockopt函數原型
setsockopt(設置套接字的屬性)
所需頭文件
#include <sys/types.h>
#include <sys/socket.h>
函數說明
設置套接字的屬性
函數原型
int setsockopt(int s, int level, int optname,
const void *optval, socklen_t optlen)
函數傳入值
s
socket文件描述符
level
SOL_SOCKET:通用套接字選項
IPPROTO_IP:IP選項
IPPROTO_TCP:TCP選項
optname
設置的選項名,具體見表18-3
optval
設置的屬性值
optlen
optval的長度
函數返回值
成功:0
失敗:-1,失敗緣由存於error中
(3)getsockopt、setsockopt函數舉例
sockopt.c源代碼以下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
int main()
{
int sockfd,optval,optlen = sizeof(int);
int sndbuf = 0 ;
int rcvbuf = 0 ;
int flag;
if((sockfd = socket(AF_INET,SOCK_STREAM,0))<0)
{
perror("socket") ;
return -1 ;
}
getsockopt(sockfd,SOL_SOCKET,SO_TYPE,&optval,&optlen);
printf("optval = %d\n",optval);
optlen = sizeof(sndbuf);
flag = getsockopt(sockfd,SOL_SOCKET,SO_SNDBUF,&sndbuf,&optlen);
printf("sndbuf=%d\n",sndbuf) ;
printf("flag=%d\n",flag) ;
sndbuf = 51200;
flag = setsockopt(sockfd,SOL_SOCKET,SO_SNDBUF,&sndbuf, optlen);
sndbuf=0 ;
flag = getsockopt(sockfd,SOL_SOCKET,SO_SNDBUF,&sndbuf,&optlen);
printf("sndbuf=%d\n",sndbuf) ;
printf("flag=%d\n",flag) ;
close(sockfd);
return 0 ;
}
編譯 gcc sockopt.c -o sockopt。
執行 ./sockopt, 執行結果以下:
optval = 1
sndbuf=16384
flag=0
sndbuf=102400
flag=0
4. UDP讀寫函數
UDP套接字是無鏈接協議,必須使用sendto函數發送數據,必須使用recvfrom函數接收數據,發送時需指明目的地址。sendto函數與send功能基本相同,recvfrom與recv功能基本相同,只不過sendto函數和recvfrom函數參數中都帶有對方地址信息,這兩個函數是專門爲UDP協議提供的。
(1)sendto函數原型
sendto(經過socket文件描述符發送數據到對方)
所需頭文件
#include <sys/types.h>
#include <sys/socket.h>
函數說明
經過socket文件描述符發送數據到對方,用於UDP協議
函數原型
ssize_t sendto(int s, const void *buf, size_t len, int flags,
const struct sockaddr *to, socklen_t tolen)
函數傳入值
s
socket文件描述符
buf
發送數據的首地址
len
發送數據的長度
flags
0:默認方式發送數據,flags還能夠設爲如下標誌的組合
MSG_OOB:發送帶外數據
MSG_DONTROUTE:告訴IP協議,目的主機在本地網絡,沒有必要查找路由表
MSG_DONTWAIT:設置爲非阻塞操做
MSG_NOSIGNAL:表示發送動做不肯被SIGPIPE信號中斷
to
存放目的主機IP地址和端口信息
tolen
to的長度,可設置爲sizeof(struct sockaddr)
函數返回值
成功:實際發送的字節數
失敗:-1,失敗緣由存於error中
(2) recvfrom函數
recv(經過socket文件描述符從對方接收數據)
所需頭文件
#include <sys/types.h>
#include <sys/socket.h>
函數說明
經過socket文件描述符從對方接收數據,用於UDP協議
函數原型
ssize_t recvfrom(int s, void *buf, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen)
函數傳入值
s
socket文件描述符
len
可接收數據的最大長度
flags
0:默認方式接收數據,flags還能夠設爲如下標誌的組合
MSG_OOB:接收帶外數據
MSG_PEEK:查看數據標誌,返回的數據並不在系統中刪除,若是再次調用recv函數會返回相同的數據內容
MSG_DONTWAIT:設置爲非阻塞操做
MSG_WAITALL:強迫接收到len大小的數據後才返回,除非有錯誤或有信號產生
fromlen
from的長度,可設置爲sizeof(struct sockaddr)
函數傳出值
buf
接收數據的首地址
from
存放發送方的IP地址和端口
函數返回值
成功:實際發送的字節數
失敗:-1,失敗緣由存於error中---------------------