第16章 网络IPC:套接字总结
1 套接字是通信端点的抽象
创建套接字:
int socket(int domain,int type,int protocol)
domain:通信域 AF_INET、AF_INET6、AF_LOCAL、AF_UNSPEC
type:套接字类型,SOCK_DGRAM、SOCK_STREAM、SOCK_SEQPACKET、SOCK_RAW
protocol:通常为0,表示domain和type默认的协议
linux中套接字使用文件描述符实现的,文件描述符上使用的大多数函数可以用于套接字
套接字输入输出:
int shutdown(int sockfd,int how)
how:SHUT_RD、SHUT_WR、SHUT_RDWR
2 网络寻址
字节序转换:
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostint32)
uint16_t htons(uint16_6 hostint16)
uint32_t ntohl(uint32_5 netint32)
uint16_t ntohs(uint16_t netint16)
地址格式:
通用地址结构: struct sockaddr { sa_family_t sa_family; char sa_data[14]; };
IPv4(AF_INET)地址格式 struct sockaddr_in { sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; };
IPv6(AF_INET6)地址格式: struct sockaddr_in6 { sa_family_t sin6_family; in_port_t sin6_port; uint32_t sin6_flowinfo; struct in6_addr sin6_addr; uint32_t sin6_scope_id; };
二进制与点分十进制格式转化函数: const char *inet_ntop(int domain,void *addr,char *str,socklen_t size) int inet_pton(int domain,const char *str,void *addr)
地址查询:
主机信息: struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_length; char *h_addr_list; }; #include <netdb.h> struct hostent *gethostent() void sethostent(int stayopen) void endhostent()
网络信息: struct netent { char *n_name; char **n_aliases; int n_addrtype; uint32_t n_net; }; #include <netdb.h> struct netent *getnetbyaddr(uint32_t net,int type) struct netent *getnetayname(const char *name) struct netent *getnetent() void setnetent(int stayopen) void endnetent();
协议信息: struct protoent { char *p_name; char **p_aliases; int p_proto; }; #include <netdb.h> struct protoent *getprotobyname(const char *name) struct protoent *getprotobynumber(int proto) struct protoent *getprotoent() void setprotoent(int stayopen) void endprotoent()
服务信息: struct servent { char *s_name; char **s_aliases; int s_port; char *s_proto; }; #include <netdb.h> struct servent *getservbyname(const char *name,const char *proto) struct servent *getservbyprot(int port,const char *proto) struct servent *getservent() void setservent(int stayopen) void endservent()
套接字与地址绑定:
#include <sys/socket.h> 绑定: int bind(int sockfd,const struct sockaddr *addr,socklen_t len) 查看套接字绑定的地址: int getsockname(int sockfd,struct sockaddr *addr,socklen_t len) 查看套接字连接的地址: int getpeername(int sockfd,struct sockaddr *addr,socklen_t *len)
3 建立连接
#include <sys/socket.h> int connect(int sockfd,struct sockaddr *addr,socklen_t len) int listen(int sockfd,int backlog) int accept(int sockfd,struct sockaddr *addr,socklen_t *len)
4 数据传输
#include <sys/socket.h> ssize_t send(int sockfd,const void *buf,size_t nbytes,int flag) flag: MSG_DONTROUTE:勿将数据路由出本地网络 MSG_DONTWAIT:允许阻塞操作 MSG_EOR:如果协议支持,此为记录结束 MSG_OOB:如果协议支持,此为带外数据
#include <sys/socket.h> ssize_t sendto(int sockfd,const char *buf,size_t nbytes,int flag,const struct sockaddr *destaddr,socklen_t destlen) 同send函数相比,允许非连接的套接字指定发送目标地址