套接字(socket)
概念
套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。
通信的实质
两个主机之间的通信,可以认为是两个进程的通信,也可以认为其实是两个
socket 套接字之间的通信。
通信五元组
- 源 IP 地址
- 源端口号
- 目的 IP 地址
- 目的端口号
- 传输层协议
(通过通信五元组就能够标识一条通信道路)
流程图示
套接字常用接口
1. 创建套接字
int socket(int domain, int type, int protocol);
参数:
domain: 地址域,不同的协议版本有着不同的地址结构
常用的有 AF_INET(ipv4) AF_INET6(ipv6)
type: 套接字类型 tcp(流式套接字) SOCK_STREAM udp(数据报套接字)SOCK_DGRAM
protocol: 传输协议, tcp(IPPROTO_TCP) udp(IPPROTO_UDP)
返回值: 成 套接字的操作句柄 败 -1
2. 为套接字绑定地址信息(绑定自己的)
客户端不推荐,因为系统会帮助绑定,这样可以避免端口冲突,服务端必须自己绑定
int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
参数:
sockfd: 套接字的操作句柄
my_addr: 要绑定的地址信息,这是一个结构体,需要用地址信息给结构体的每一个变量赋值(因为不同的地址结构开头都是一致的,为了避免出错,这里需要进行结构体强转)
addrlen: 要绑定的地址信息的长度,也就是my_addr这个结构体的长度
返回值: 成 0 败 -1
3.接收数据并且保存发送端的地址信息
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
参数:
sockfd: 操作句柄
buf: 一块缓冲区,用来接受取出的信息
len: 要接受的数据长度
flag: 默认为0.表阻塞
src_addr: 发送方的地址信息
addrlen: 地址信息的长度
返回值: 成 实际接受数据的长度 败 -1
4.发送数据
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
参数:
sockfd: 操作句柄
buf: 发送数据的首地址
len: 要发送的数据长度
flag: 默认为0.表阻塞
dest_addr: 接受方的地址信息
addrlen: 地址信息的长度
返回值: 成 实际发送数据的长度 败 -1
5.关闭套接字
int close(int fd);
fd:要关闭的句柄
6.网络/主机字节序转化接口
网-> 主 ntohl(转32位) ntohs(转16位)
主-> 网 htonl(转32位) htons(转16位)
7.ip的字节序转化
struct in_addr_t inet_addr(char *p); //字符串ipv4转网络字节序的ip
struct* inet_ntoa(struct in_addr nip); //网络字节序ip转字符串ipv4
上图中用到的结构体解释
代码演示