套接字地址结构
(1)IPv4的套接字地址结构
#include<netinet/in.h>
struct in_addr{ //定义该结构来表示IPv4地址
in_addr_t s_addr; //32位IPv4的地址
};
struct sockaddr_in{ //套接字地址结构
uint8_t sin_len; //1字节,表示整个结构的长度=16字节
sa_family_t sin_family; //1字节AF_INET,表示是IPv4地址族
in_port_t sin_port; //2字节,uint16_t,16位的端口号,0~65535
struct in_addr sin_addr; //4字节,32位IPv4地址
char sin_zero[8]; //8字节,unused,用来补充位数,一般为0
};
IPv4通配地址为sin_addr=htonl(INADDR_ANY);通配端口为0
(2)IPv6套接字地址结构
#include<netinet/in.h>
struct in6_addr{
uint8_t sa_addr[16]; //128位IPv6地址,IPv4为32位in_addr_t(uint32)
}
struct sockaddr_in6{
uint8_t sin6_len; //1字节,表示整个结构的长度=28字节
sa_family_t sin6_family; //1字节,AF_INET6,表示是IPv6地址族,IPv4为AF_INET
in_port_t sin6_port; //2字节,端口号
uint32_t sin6_flowinfo; //4字节,流量窗口信息,未定义,IPv4没有
struct in6_addr sin6_addr; //16字节,IPv6地址,IPv4为in_addr
uint32_t sin6_scpor_id; //4字节,用来标识地址所在范围的接口,IPv4没有
}
IPv6通配地址为sin6_addr=in6addr_any;通配端口为0
(3)通用套接字地址结构1
#include<sys/socket.h>:
struct sockaddr{
uint8_t sa_len;
sa_family sa_family;
char sa_data[14];
}
(4)通用套接字地址结构2
#include<netinet/in.h>
struct sockaddr_storage{
uint8_t ss_len; //本结构长度
sa_family_s sa_family; //地址族,AF_xxx。
}
POSIX数据类型
符合POSIX(可移植操作系统接口)的结构需要至少3个字段:sin_family、sin_addr和sin_port。
POSIX定义的常见数据类型:
地址字节操作函数
网络IO函数
#include<stdio.h>中默认打开三个FILE类型的指针
- stdin:标准输入(键盘输入)
- stdout:标准输出(终端输出)
- stderr:标准错误
字符串操作函数
套接字编程函数
int family:指明协议族类型,协议族类型共有:
int type:指明套接字类型
int protocol:指明传输协议类型。可以设为0,表示指定family和type的默认形式。
退出
#include<stdlib.h>
exit函数:exit是系统调用级别的,是一个函数,它表示了一个进程的结束。 exit是在调用处强行退出程序,运行一次程序就结束。这个状态标识了应用程序的一些运行信息,这个信息和机器和操作系统有关。
1、**exit(1)**表示异常退出,在退出前可以给出一些提示信息,或在调试程序中察看出错原因。
2、**exit(0)**表示正常退出
3、return是语言级别的,是关键字,它表示了调用堆栈的返回,return用于结束一个函数的执行,将函数的执行信息传出个其他调用函数使用,如果返回的是main函数,则为退出程序。
错误处理
#include<errno.h>
可以调用strerror函数将错误信息打印出来。
printf("error=%d(%s)!!!\n", errno, strerror(errno));