模型
#include
socket()
//創建網絡端點,返回socket文件描述符,失敗返回-1設errnoint socket(int domain, int type, int protocol);
domain?:協議族(protocol family)(網絡通訊(IP)還是本地通訊(xxx.socket))
- AF_INET用于實現給予ipv4網絡協議的網絡協議
type?:協議(TCP還是UDP) - SOCK_DGRAM?//數據報套接字, 實現包括但不限于UDP協議, which is不可靠,無連接的數據報通信方
protocol: 特殊協議, 一般給0
準備通信地址:
struct sockaddr{ //主要用于函數的形參類型, 很少定義結構體變量使用, 叫做通用的通信地址類型//$man bind sa_family_t sa_family; char sa_data[14];}struct sockaddr_in{ //準備網絡通信的通信地址 //$man in.h sa_family_t sin_family; //協議族, 就是socket()的domain的AF_INET in_port_t sin_port; //端口號 struct in_addr sin_addr; //IP地址, //當前網段的最大ip地址是廣播地址,即,xxx.xxx.xxx.255。 //255.255.255.255在所有網段都是廣播地址}struct in_addr{ in_addr_t s_addr; //整數類型的IP地址}
bind()
//把通信地址和socket文件描述符綁定,用在服務器端,成功返回0,失敗返回-1設errnoint bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd: socket文件的fd(returned by socket())
addr: 需要強制類型轉換成socketaddr_un或soketaddr_in, 參見上
addrlen: 通信地址的大小, 使用sizeof();
sendto()
//向指定的socket和相應的地址發送消息,成功返回實際發送數據的大小,失敗返回-1設errnossize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
dest_addr:目標地址(收件人信息)
addrlen: 目標地址的大小
ANote
- send(sockfd, buf, len, flags);等價于 sendto(sockfd, buf, len, flags, NULL, 0);
- recv()/ send()表示通過sockfd收發數據, 因為tcp下, 收發之前sockfd已經和相應的地址連接了,所以不需要指定收發誰的/給誰, 但是udp因為收發時沒有連接, 所以需要指定
recvfrom()
//從指定的socket和相應的地址接受消息,并提供來電顯示的功能,成功返回實際接收的數據大小,失敗返回-1設errnossize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
src_addr: 結構體指針, 用于保存數據發送方的通信地址
addrlen: 指針類型, 用于保存發送方的地址大小
Note:
- recv(sockfd, buf, len, flags); 等價于 recvfrom(sockfd, buf, len, flags, NULL, 0);
- accept() and recvfrom() 后面的參數是用來提供來電顯示的
- 一個server對應多個client
- server可以不知道client的地址, 但是client得知道server的地址
- send data 一定要知道對方地址
- receive data不需要知道對方地址
- TCP/IP的socket都是SOCK_STREAM的,全程連接,通過socket就能找到對方地址, send data的話,直接丟給socket就行
- UDP/IP的socket是SOCK_DGRAM的,不全程連接,不能通過socket找到對方,send data的話,server中需要使用recvfrom()來知道client的地址, 所以肯定要sendto();client本來就知道server的地址, 直接sendto()
- recvfrom()的唯一意義就是在udp-server中配合sendto()使用
- 因為不能通過socket找到對方, 只要是udp發消息, 就得通過sendto()
例子-一對一的upd/ip協議的服務器模型
//udp/ip server 五步走#include
//udp/ip client#include
評論
查看更多