```cpp
	#include <iostream>
	#include <cstring>
	#include <unistd.h>
	#include <netdb.h>
	#include <cstdlib>
	#include <sys/types.h>
	#include <sys/socket.h>
	#include <arpa/inet.h>
```

# tips
	+ 所有网络函数失败基本是返回 -1,errno被设置

# socket


	原型:  int socket(int domain, int type, int protocol)

		+ domain 协议族
		 \	PF_INET			# IPv4 互联网协议族
		 \	PF_INET6 		# IPv6 互联网协议族
		 \	PF_LOCAL		# 本地通讯地址族

		+ type 数据传输类型
		 \	SOCK_STREAM		# 面向连接;  数据不丢失;  数据顺序不错乱;  双向通道;
		 \  SOCK_DGRAM		# 无连接;	 数据可能丢;  数据可能错乱;	   效率高;

		+ protocol 最终使用协议
		 \  IPPROTO_TCP
		 \  IPPROTO_UDP
		 \  0				# 编译器自动识别

# 主机字节序和网络字节序
	
	+ 大端序和小端序 (如果数据大于1B,CPU在内存中存放数据的方式)
	 \  大端序	低位字节在高位,高位字节在低位
	 \  小端序	低位字节在低位,高位字节在高位 (INTEL)

	## 字节序不同的系统字节传输数据,可能会出现问题,所以网络字节序约定使用大端序
	+ c提供了4个库用于主机字节序和网络字节序之间的转换
	 \  uint16_t htons(uint16_t hostshort);	// 2字节的整数
	 \  uint32_t htonl(uint32_t hostshort);	// 4字节的整数
	 \  uint16_t ntons(uint16_t netshort);	// 2字节的整数
	 \  uint32_t ntonl(uint32_t netshort);	// 4字节的整数
		// h	host主机
		// to 	转换
		// n 	network网络
		// s	short(2byte)
		// l 	long(4byte)

# IP地址和通讯端口
	+ IPv4(4byte) 端口(2byte)

# 大小端序的处理
	+ 在网络编程中数据收发有自动转换,只有sockaddr_in结构成员变量填充数据时，才需要考虑字节序

# 结构体
	
	## sockaddr
	```cpp
		struct sockaddr { 	// connect() bind() 都需要
			unsigned short sa_family;	// 协议族
			unsigned char sa_data[14];	// 14byte的端口和地址
		}
	```	

	## sockaddr_in
	```cpp
		struct sockaddr {	// 为了方便操作，大小与sockaddr相同，可以强制转换
			unsigned short sin_family;	// 协议族
			unsigned short sin_port;	// 2byte端口号
			//struct in_addr sin_addr;	// 4byte地址
			unsigned int sin_addr;		// 4byte地址
			unsigned char sin_zero[8];	// 保留，长度对齐
		}
	```

# gethostbyname函数
	
	+ 用 域名/主机名/字符串IP 转换成大端序
	```cpp
		struct hostent *gethostbyname(const char *name);
		struct hostent {
			char *h_name;				// 主机名
			char **h_aliases;			// 主机所有别名的字符串数组
			short h_addrtype;			// 主机IP类型,IPv4或IPv6
			short h_length;				// 主机IP长度
			char **h_addr_list;			// 主机IP地址,以网络字节序存储
		}
		#define h_addr h_addr_list[0]

		// 转换后，用 memcpy(&servaddr.sin_addr, h->h_addr, h->h_length);
	```

# 字符串IP和大端序IP的转换
	## atoi() 把字符串IP转换成大端序
	```cpp
		typedef unsigned int in_addr_t;	//4byte大端序IP

		// 字符串转大端序IP,转换后IP赋给sockaddr_in.in_addr.s_addr
		in_addr_t inet_addr(const char *cp);

		// 字符串转大端序IP,转换后IP赋给sockaddr_in.in_addr
		int inet_aton(const char *cp, struct in_addr *inp);

		//大转字符串,用于服务端解析IP
		char *inet_ntoa(struct in_addr in);
	```

