簡單的客戶端C與服務器S通信
服務端S使用函數及其順序:
套接字文件描述符狀態
socket() 阻塞
bind() 阻塞
listen() 監聽
accept() 監聽/阻塞,(等待客戶端的connect申請,收到connect申請後:ESTABLISHED狀態 )
recv() ESTABLISHED
close() 關閉
客戶端C使用函數及其順序:
套接字文件描述符狀態
socket() 阻塞
connet() 阻塞,三次握手後:ESTABLISHED狀態
send() ESTABLISHED
close() 關閉
函數的作用:
socket 返回的套接字文件描述符A默認爲阻塞,但可通過setsockopt函數設置該文件描述符的屬性
bind 使套接字A綁定IP和端口,S要綁定本機IP和端口,C要綁定S的IP和端口
listen 使A進入監聽狀態
accept S處於監聽的A等待C的鏈接申請,當C通過connect函數發來的申請,S與C進行三次握,握手成功返回一個新的文件描述符B用 於與C通信同時狀態爲ESTABLISHED
connect C向S發送通信申請,三次握手成功後,文件描述符爲ESTABLISHED
send C用於向S發送數據
recv S用於接收C發過來的數據
函數的參數:
協議族 套接字類型
int socket(int domain, int type, int protocol)
PF_INET SOCK_STREAM
PF_UNIX SOCK_DGRAM
PF_NS SOCK_RAW
PF_IMPLINK
<sys/types.h>
<sys/socket.h>
返回:成功:套接字文件描述符
失敗:-1
相關的數據結構:
int bind (int sockfd, struct sockaddr *addr, int addrlen)
由socket返回 地址屬性 指定地址屬性長度
返回:0或-1
通用地址結構
struct sockaddr
{
u_short sa_family; //協議族
char sa_data[14]; //14字節協議地址
}
intetnet協議地址結構
struct sockaddr_in
{
u_short sin_family; //協議族
u_short sin_port; //端口
struct in_addr sin_addr; //IPV4地址
char sin_zero[8]; //
}
struct in_addr
{
in_addr_t s_addr; //u32 IP地址
}
在使用bind是必須初始化以上數據結構
int listen(int sockfd, int backlog)
監聽連接的套接字 指定連接的隊列長度(連接數)
<sys/types.h>
<sys/socket.h>
由socket返回 發送緩衝首地址 發送字節數 發送方式
=0時相當於write函數
<sys/socket.h>
返回:實際發送字節數 或-1
ssize_t recv(int sockfd, const void *buf, size_t len, int flags)
參數同send
其他函數:
memset() 和 bzero()用於清空 地址屬性機構體
sendto()
recvfrom()