1.通用套接字地址结构
#include<sys/socket.h>
struct sockaddr{
uint8_t sa_len;
sa_family_t sa_family;
char sa_data[14];
};
2.IPv4套接字地址结构
#include<netinet/in.h>
struct in_addr{
in_addr_t s_addr;//32bit IPv4地址
};
struct sockaddr_in{
uint8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
3.IPv6套接字地址结构
#include<netinet/in.h>
struct in_addr{
in_addr_t s_addr;//32bit IPv4地址
};
struct sockaddr_in{
uint8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
4.字节顺序转换
#include<netinet/in.h>
uint16_t htons(uint_16 host16bitvalue);//转为网络字节顺序,16Bit长度
uint32_t htonl(uint_32 host32bitvalue);//转为网络字节顺序,32Bit长度
uint16_t ntohs(uint_16 net16bitvalue);//转为主机字节顺序,16Bit长度
uint32_t ntohl(uint_32 net32bitvalue);//转为主机字节顺序,32Bit长度
5.地址转换函数
#include<arpa/in.h>
int inet_aton(const char strptr,struct in_addr *addrptr);
//将字符串类型如11.1.11.11,转为数据包需要的数据类型。成功返回1,否则为0
char *inet_ntoa(struct in_addr inaddr);
//返回字符串形式的IP地址
int inet_pton(int family,const char strptr,void *addrptr);
//通过family选择IPv4和IPv6。成功返回1,表达式无效为0,出错为-1
const char *inet_ntop(int family,const void *addrptr, char *strptr,size_t len);
//返回字符串形式的IP地址,否则为NULL。(len为存储缓冲区长度)
6.TCP/IP连接函数
#include<sys/socket.h>
int socket(int family,int type,int protocol);
int bind(int sockfd,const struct sockaddr *myaddr,sock_len_t addrlen);
int listen(int sockfd,int backlog);
int accept(int sockfd,struct sockaddr *cliaddr,socklen_t *addrlen);
int connect(int sockfd,const struct sockaddr *servaddr,socklen_t addrlen);
//以上函数出错时都返回-1
7.TCP/IP函数调用
服务端:socket->bind->listen->accept
客户端:socket->connect
8.其他
任意IP地址宏INADDR_ANY
服务器bind一个端口号,其他客户端通过服务器IP和端口号进行连接,客户端(如果没有调用bind)端口号自动分配。
family宏:AF_INET,IPv4,AF_INET6。(常用的)
socket函数,type宏:SOCK_STREAM,TCP通讯;SOCK_GRAM,UDP通讯。(常用的)