相關結構 相關函數 主調用 如果函數調用失敗,都返回 1,調用失敗會在全局變數error里有相應的值 不涉及到讀取、發送的時候,調用正常都返回0 socket() 創建套接字 family: 協議或地址族,TCP/IP為PF_INET,(ipv6為PF_INET6),也可以使用AF_INET typ ...
相關結構
//下邊這兩個結構定義在<sys/types.h>里
//一般的地址結構,只能用於覆蓋(把其他地址轉換為此類型),且只能引用該地址的sa_family欄位
struct sockaddr
{
unsigned char sa_len; //total length,整個結構體的長度,舊版本沒有
unsigned short sa_family; //地址族
char sa_data[14]; //地址的值
//TCP/IP使用的地址結構
struct sockaddr_in
{
unsigned char sin_len; //total length
short int sin_family; //地址族,一般為AF_INET(ipv4),ipv6為(AF_INET6)
unsigned short int sin_port; //埠號
struct in_addr sin_addr; //ip地址
char sin_zero[8]; //沒有使用(設置為0)
}
相關函數-主調用
如果函數調用失敗,都返回-1,調用失敗會在全局變數error里有相應的值
不涉及到讀取、發送的時候,調用正常都返回0
socket()
創建套接字
int socket(int family, int type, int protocol)
family: 協議或地址族,TCP/IP為PF_INET,(ipv6為PF_INET6),也可以使用AF_INET
type: 套接字類型
- 流式套接字:SCOK_STREAM, TCP
- 數據報套接字:SOCK_DGRAM,UDP
- 原始套接字:SOCK_RAW,沒有經過處理的IP數據包,可以根據自己程式的要求進行封裝
protocol:用來指定socket所使用的傳輸協議編號,通常設為0即可。
調用成功返回描述符
connect()
為套接字指明遠程端點的地址。為TCP時,connect使用三次握手建立連接;為UDP時,connect僅指明遠程端點,但是不向他發送任何數據
int connect(int sock, struct sockaddr \*serv_addr, int addrlen)
sock: 目的伺服器的socket描述符
serv_addr:包含目的機器ip地址和埠號的指針
addrlen:sizeof(struct sockaddr)
調用成功返回0
send()/write() -TCP
linux下可以使用write(),將報文傳遞給目標主機
(int sock, char\* msg, int msglen, int flags);
flags:控制bit,指明是否接受帶外數據和是否預覽報文,一般為0
write(int sock, char* buf, int buflen)
buf:含有數據緩存的地址
buflen:buf中的位元組數
這兩個函數調用成功時都返回傳送的位元組數
recv()/read() -TCP
從套接字中接收數據
nt recv(int sock, char\* buf, int len, int flags)
buf:存放數據的緩存地址
len:緩存的長度
flags:控制bit,指明是否接受帶外數據和是否預覽報文一般為0
read(int sock, char* buf, int buflen)
調用成功都返回讀取的位元組數
sendto() -UDP
從一個結構中獲取目的地址,然後發送報文
int sendto(int sock, char \*msg, int msglen, int flags, const struct sockaddr\* to, int\* tolen);
tolen:地址結構的位元組長度
成功時,返回已發送的位元組數
recvfrom() -UDP
從套接字獲取下一個傳入報文,並記錄發送者的地址
int recvfrom(int sock, char\* buf, int buflen, int flags, struct sockaddr\* from, int\* fromlen)
```
fromlen:緩存的長度,返回時為發送者地址的大小。
成功調用時,返回報文中的位元組數
### bind()
主要由伺服器使用,指明本地ip地址和協議埠號
int bind(int sock, struct sockaddr *localaddr, int addrlen)
成功時返回0
### listen() -TCP
伺服器調用,使套接字處於被動狀態(準備接受傳入請求)
int listen ( sock,queuelen)
queuelen:傳入鏈接請求的隊列大小(通常最大不超過5)
### accept() -TCP
bind->listen->accept,從隊列中取走下一個鏈接請求(或者一直在那裡等待下一個連接請求到來),為請求創建新套接字,並返回新套接字描述符。
int accept(int sock, struct sockaddr * addr, int* addrlen)
addrlen:初始指明為addr的大小,調用返回時為存儲在addr中的位元組數
### close()
終止通信,刪除套接字,任何正在套接字上等待被讀取的數據都將被拋棄。
linux使用了引用計數機制,可以多個進程共用一個套接字。close每被調用一次,引用計數減1,引用計數為0時才釋放。
int close(int sock)
成功時返回0
### shutdown()
部分關閉連接
int shutdown(int sock,int direction )
direction:0,終止進一步輸入;1,終止進一步輸出;2,終止輸入和輸出
## 輔助函數
### 整數轉換
TCP/IP協議首部使用的二進位採用網路位元組順序(表示整數時,最高位元組在前)
為了機器和網路位元組順序相容,應當始終調用轉換函數
htons(host to network short)
ntohs
htonl
ntohl
### 地址轉換inet_addr
接受字元串(點分十進位),返回等價二進位表示的地址
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
```
查找功能變數名稱對應ip地址gethostbyname
接收ASCII字元串功能變數名稱,返回hostent結構,定義在<netdb.h>
中
struct hostent
{
char* h_name, //正式主機名
char** h_aliases, //其他別名列表
int h_addrtype, //地址類型
int h_length, //地址長度
char** h_addr_list //一般主機可以有多個ip地址,h_addr_list用來
保存多個ip地址
}
#define h_addr h_addr_list[0] //為了與早期的版本相容
由服務名字得到熟知埠getservbyname
成功則返回一個servent結構指針,發生差錯就返回空指針,結構定義在<netdb.h>
中
servent* getservbyname(char\* name, char\* proto)
struct servent
{
char* s_name; //正式服務名
char** s_aliases; //其他別名列表
int s_port; //該服務使用的埠
char *s_proto; //伺服器所用的協議
};
```
根據協議名找到該協議的正式整數值getprotobyname(char* name)
成功就返回protoent結構指針,結構定義在<netdb.h>
中
struct protoent
{
char\* p_name; //協議正式名
char\*\* p_aliases; //協議的別名列表
int p_proto; //正式協議名
}
獲取主機名字gethostname
以字元串形式返回主機名
int gethostname(char\* name, namelen)
name:放置名字的字元數組的地址
獲取遠程端點地址getpeername
需要已經建立鏈接
int getpeername(int sock, sockaddr\* remaddr, int\* addrlen)
remaddr:含有對端地址的sockaddr指針
addrlen:調用前為第二個參數的長度,調用後為遠程端點地址的實際長度
設置/查看套接字參數
getsockopt()
setsockopt()
相關頭文件
<sys/types.h> //primitive system data types(包含很多類型重定義,如pid_t、int8_t等)
<sys/socket.h> //與套接字相關的函數聲明和結構體定義,如socket()、bind()、connect()及struct sockaddr的定義等
//上邊兩個sock調用必須包含
<netinet/in.h> //某些結構體聲明、巨集定義,如struct sockaddr_in、struct inaddr 、PROTO_ICMP、INADDR_ANY等
<sys/types.h> //primitive system data types(包含很多類型重定義,如pid_t、int8_t等)
<sys/socket.h> //與套接字相關的函數聲明和結構體定義,如socket()、bind()、connect()及struct sockaddr的定義等
<sys/ioctl.h> //I/O控制操作相關的函數聲明,如ioctl()
<stdlib.h> //某些結構體定義和巨集定義,如EXIT_FAILURE、EXIT_SUCCESS等
<netdb.h> //某些結構體定義、巨集定義和函數聲明,如struct hostent、struct servent、gethostbyname()、gethostbyaddr()、herror()等
<arpa/inet.h> //某些函數聲明,如inet_ntop()、inet_ntoa()等
<netinet/in.h> //某些結構體聲明、巨集定義,如struct sockaddr_in、PROTO_ICMP、INADDR_ANY等