套接字与socket函数
文章目录
学习目标:
掌握IP地址转换函数
了解sockaddr地址结构
掌握socket、bind、listen、accept、connet函数。
套接字(socket):
套接字(socket): 就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象,一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。(本质:两个网络各自通信连接中的端点)
在通信过程中,套接字一定是成对出现的。
网络字节序:
网络字节序: 是TCP/IP中规定好的一种数据表示格式。
小端法:(PC本地存储) 高位存高位地址,低位存地位地址。
大端法:(网络存储)高位存低地址,低位存高地址。
**转换函数: **
- htons:把unsigned short类型从主机序转换到网络序。
- htonl:把unsigned long类型从主机序转换到网络序。
- ntohs:把unsigned short类型从网络序转换到主机序。
- ntohl:把unsigned long类型从网络序转换到主机序。
ip地址转换函数:
inet_pton函数: 可以加个你点分十进制的文本IP地址转换为二进制网络字节序的IP地址。
int inet_pton(int af,const char *src,void *dst);
参数
af:AF_INET(IPV4)、AF_INET6(IPV6)
src:传入参数,IP地址(点分十进制)
dst:传出、转换后的网络字节序的IP地址。
返回值
成功:1
失败:-1
异常:0 说明sec指向的不是一个有效的ip地址
const char *inet_pton(int af,const void*src,char *dst,socklen_t size);
参数
af:AF_INET(IPV4)、AF_INET6(IPV6)
src:网络字节序IP地址
dst:本地字节序
size:dst的大小
返回值
成功:dst
失败:NULL
sockaddr地址结构:
sockaddr地址结构: 用于存储参与(IP)Windows/linux套接字通信的计算机上的一个internet协议(IP)地址。为了统一地址结构的表示方法 ,统一接口函数,使得不同的地址结构可以被bind()、connect()、recvfrom()、sendto()等函数调用。(在网络环境唯一标识一个进程)
struct sockaddr_in{
short int sin_family;
unsigned short int sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
参数
sin_family:指代协议族,AF_INET、AF_INET6
sin_port:存储端口号(使用网络字节顺序)
sin_addr:存储IP地址,使用in_addr这个数据结构。
sin_zero:是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节。
socket函数:
socket函数: 函数用于根据指定的地址族、数据类型和协议来分配一个套接口的描述字及其所用的资源。如果协议protocol未指定(等于0),则使用缺省的连接方式。(头文件sys/socket.h)
int socket(int domain,int type,int protocol);//创建一个套接字
参数
domain:指代协议族,AF_INET、AF_INET6、AF_UNIX
type:SOCK_STREAM、SOCK_DGRAM
protocol:0。
返回值
成功:新套接字锁对应文件描述符
失败:-1 errno
bind函数:
bind函数: 通过给一个未命名套接口分配一个本地名字来为套接口建立本地捆绑(主机地址/端口号)。
int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);//给socket绑定一个地址结构(IP + PORT)
参数
sockfd:socket函数返回值
addr:传入参数(struct sockaddr *)&addr
addrlen:sizeof(addr)地址结构的大小。
addr一般初始化方法:
struct sockaddr_in addr;
addr.sin_family = AF_INET;//ipv4
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY就是指定地址为0.0.0.0低地址,表示不确定地址
返回值
成功:新套接字锁对应文件描述符
失败:-1 errno
accept函数:
accept函数: 从s的等待连接队列中抽取第一个连接,创建一个与s同类的新的套接口并返回句柄。(阻塞等待客户端建立连接)
int accept(int sockfd,struct sockaddr *addr,socklen_t addrlen);
参数
sockfd:socket函数返回值
addr:传出参数成功与服务器建立连接的那个客户端地址结构(IP + PORT)
addrlen:socklen_t clilt_addr_len = sizeof(addr) 传入传出参数。&clit_addr_len 入:addr的大小。 出:客户端addr实际大小
返回值
成功:能与客户端进行数据通信的socket对应的文件描述符
失败:-1 errno
connect函数:
connect函数: 用于建立与指定socket的连接。
int connect(int sockfd,const struct sockaddr *addr,socklen_t addrlen);//使用现有的socket与服务器建立连接
参数
sockfd:socket函数返回值
addr:服务器地址结构(IP + PORT)
addrlen:传入参数,服务器的地址结构大小。
addr一般初始化方法:
struct sockaddr_in srv_addr;//服务器地址结构
srv_addr.sin_family = AF_INET;//ipv4
srv_addr.sin_port = htons(port);
inet_pton(AF_INET,"服务器的ip地址",&srv_addr.sin_addr.s_addr);
返回值
成功:0
失败:-1 errno
补充:
TCP通信流程: