socket通讯
网络字节序
- 小端法: 高位存高地址,低位存低地址。 (intel架构的存储方式)
- 大端法:高位存低地址,低位存高地址。(网络传输的方式)
#include
// 将本地转网络,转IP 转192.168.1.11->string->atoi->int->htonl->网络字节序,可以使用 int inet_pton(); 进行直接转换
uint32_t htonl(uint32_t hostlong);
// 本地转网络,转port
uint16_t htons(uint16_t hostshort);
// 网络转本地,转ip
uint32_t ntohl(uint32_t netlong);
// 网络转本地,转port
uint16_t ntohs(uint16_t netshort);
// string转网络字节
int inet_pton(int af, const char * restrict src, void * restrict dst);
// af: AF_INET, AF_INET6
// src: ip地址,点分十进制
// dst: 转换之后的 网络字节序的地址
创建socket服务器的步骤
- 创建socket句柄
- bind() 绑定ip+port
- listen() 设置监听上线,同时连接数
- accept() 阻塞监听客户端连接
- read() 进行数据的读取,读取到的数据需要toupper()进行小写转大写
- write() 写入,写给客户端返回值
- 当read()读到0就是close的时候进行 close() 关闭
Socket函数分析
创建一个套接字
int socket(int domain, int type, int protocol);
- domain : 所选用的ip地址协议, AF_INET, AF_INET6
- type : 类型 SOCK_STREAM(TCP/流形式), SOCK_DGRAM(UDP/报形式)
- protocol : 代表协议号 0
返回值:
成功返回0,新套接字的文件描述
失败返回: -1
#include
fd = socket(AF_INET, SOCK_STREAM, 0)
sockaddr地址结构体分析
#include
#include
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(9527);
int dst;
inet_pton(AF_INET, "192.168.22.45", (void *)&dst);
addr.sin_addr.s_addr = dst;
addr.sin_addr.s_addr = htonl(INADDR_ANY) // INADDR_ANY 取出系统有效的任意ip地址,是二进制类型
bind(fd, (struct sockaddr *)&addr, size);
bind函数的分析
绑定函数
bind(fd, (struct sockaddr *)&addr, size);
- fd : socket文件对象
- (struct sockaddr *)&addr : 将sockaddr存储的地址结构进行强制转换成sockaddr 进行传入
- size : addr的大小,使用sizeof进行获取
listen函数分析
监听函数
int listen(int sockfd, int backlog);
- sockfd : 套接字
- backlog : 最大连接数,最大为128
- 返回值: 0, -1 error
accept函数分析
堵塞函数
int accept(int sockfd, struct sockaddr addr, socklen_t addrlen);
- sockfd : socket 函数返回值
- addr : 传出参数, 成功返回服务器的ip和端口号
- addrlen : 传入传出。入: addr的大小。 出:客户端addr的实际大小
返回值:
- 成功: 大于0,返回成功的套接字文件描述符
- 失败:返回-1
connect函数分析
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 使用现有的socket与服务器建立连接
- sockfd: socket 函数返回值
- addr: 传入服务器的地址结构
- 返回值:
- 成功:0
- 失败:-1