套接字基础
套接字是一种网络API,用来开发网络程序。提供了一种进程间通信方法,使得在相同或不同的主机上的进程能以相同的规范进行信息传送(类似于RPC),是应用层到传输层的接口。
套接字类型
Linux系统常用的两种协议:
1、 INET: IPV4
2、 INET6: IPV6
套接字类型:创建套接字的应用程序要使用的通信服务类型,主要一下:
1、 SOCK_STREAM:流套接字,提供面向连接、可靠的数据传输服务,数据按字节流、按顺序收发。TCP协议支持该套接字
2、 SOCK_DGRAM: 数据报套接字,提供无连接的服务,数据收发无序,不能保证到达,UDP支持该类型。
3、 SOCK_RAM:原始套接字,允许对低于传输层的协议或物理网络直接访问,常用于检测新的协议。
套接字地址结构
在用套接字函数编写程序时,大多数函数需要一个指向地址结构的参数。
IPV4套接字地址结构(也称“网际套接字地址结构”)
sockaddr_in,定义在头文件<netinet/in.h>;
struct sockaddr_in{
uint8_t sin_len; //套接字地址结构的长度,一般不需要设置
sa_family_t sin_family; //Internet协议族,IPV4就是AF_INET
in_port_t sin_port; //端口号,以网络字节序存储
struct in_addr sin_addr; //存放IP地址的结构体
char sin_zero[8]; //没有使用,但一般初始化为0
}
struct in_addr{
in_addr_t s_addr; //网络字节序的32位IPV4地址
}
IPV6套接字地址结构… (暂时没看。。。)
通用套接字地址结构
套接字地址结构作为一个参数传递给任一个套接字函数时,通常通过指针传递,需要将指向特定协议的地址结构的指针类型转换成指向通用地址结构的指针,然后在函数使用时强制转换即可。
通用套接字地址结构定义在<sys/socket.h>中
struct sockaddr_in ser; // 将IPV4套接字转换成通用套接字用于函数
bind(sockfd,(struct sockadr *)&ser, sizeof(ser));
套接字基本函数
字节排序函数:内存中存储字节有两种不同方法
1、 小端字节序:将低序字节存储在起始地址
2、 大端字节序:将高序字节存储在起始地址
将主机使用的字节序称为“主机字节序”,不同字节序主机能通信,规定了网络字节序。
发送前将主机字节序转换成网络字节序,接收后再转换主机字节序。
#include<netinet/in.h>
uint16_t htons(uint16_t hosts); //16位short主机-à 网络
uint32_t htonl(uint32_t host1); //32位long 主机-à 网络
uint16_t ntohs(uint16_t nets);
uint16_t ntohl(uint32_t nets);
IP地址转换函数:字符串IP地址(点分十进制)与二进制IP转换
#include<arpa/inet.h>
in_addr_t inet_addr(constchar *str); //基本不用,点分十进制->二进制,但是不验证IP合理性
int inet_aton(constchar *str, struct in_addr *numstr); //点分十进制-> 二进制numstr
char *inet_ntoa(struct in_addr inaddr);//二进制-> 点分十进制
isfdtype()函数:验证描述符是不是给定的类型。
#include <sys/stath.h>
int isfdtype(int fd, int fdtype);
比如:isfdtype(sockfd, S_IFSOCK);//测试是否为套接字描述符
值-结果参数
在参数传递过程中其值发生变化的参数称为值-结果参数。比如:
socklen_t len = sizeof(client);
accept(listenfd, (struct sockaddr*) &client, &len);
在函数调用时,结构长度是个值,告诉内核该结构的长度,使内核在写这个结构的时候不会越界,当函数返回时,结构大小的长度发生变化,变成了内核在该结构中确切存储的数据长度。
IP转换函数: