Linux驱动05 --- TCP 服务器
目录
一、TCP 服务器
1.1 介绍
1.2 公网
1.3 创建服务器套接字
1.4 绑定自身 IP
1.5 监听套接字
1.6 接受套接字连接
1.7 IP 端口复用
1.8 服务器客户端双向通信
一、TCP 服务器
1.1 介绍
服务器的主要功能 --- 消息的转发
TCP客户端连接的都是别人的公网服务器
公网服务器 IP 固定且唯一,可以在任何地方访问它
可以搭建自己的服务器,用的是自己电脑的IP,所以是在自己的电脑上有效,只要 IP 换成公网 IP, 这个服务器就可以运行在
1.2 公网
搭建的服务器,可以去验证,就是其中一人手机开热点,其他人电脑连接这个手机热点,大家的电脑在同一个网段,就可以选定其中一个同学的电脑作为服务器,其他人就可以连接服务器发消息
服务器搭建主要经历这几个过程
1.3 创建服务器套接字
函数原型
int socket(int domain, int type, int protocol)
1.4 绑定自身 IP
函数原型
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
函数参数
sockfd:服务器的套接字
struct sockaddr:在 connect 函数中见过
这个参数和 connect 的第二个参数完全相同
struct sockaddr_in
addrlen:struct sockaddr_in 结构体的大小
函数返回值
成功返回 0,失败返回负数
1.5 监听套接字
函数原型
int listen(int sockfd, int backlog)
函数参数
sockfd:服务器套接字
backlog:服务器监听套接字的最大数量
函数返回值
成功返回 0,失败返回负数
1.6 接受套接字连接
函数原型
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
函数参数
sockfd:服务器的套接字
addr:用于存放连接客户端的 IP 信息
需要定义一个变量,然后取地址放到第二个参数
socklen_t *addrlen:这是一个指针
需要定义一个变量,求出来 struct sockaddr 大小
将变量取地址放到第三个参数
函数返回值
成功返回一个大于 0 的通信套接字 --- 和对应的客户端进行通信的套接字
和不同的客户端通信真正用的是不同的 accept 的返回值
失败返回负数
1.7 IP 端口复用
服务器的 IP 会绑定失败,原因是 IP 和端口被占用
1、改程序中的的端口号 --- 重新编译运行
2、可以在程序中开 IP 和端口的复用
函数原型
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen)
函数功能:给套接字设置属性
函数参数
sockfd:要设置属性的套接字
level:套接字的种类 --- TCP 和 UDP
optname:给套接字的属性
SO_REUSEADDR
SO_REUSEPORT --- 会报错,问题是因为没有加头文件,不耽误使用
optval:需要定义一个变量,变量值为真即可,取地址放进来
optlen:定义的变量的大小
函数返回值
成功返回 0,失败返回负数
1.8 服务器客户端双向通信
收:read --- 函数是阻塞的 --- 程序会一直在这个位置等待
写:write --- 在 write 之前会有 scanf --- 函数是阻塞的 --- 程序会一直在这个位置等待如果让写和发同时进行 --- 两个 while 同时执行,就要开个线程
客户端和服务器任何一端下线都会导致另外一端的崩溃
崩溃的原因,一端的套接字已经关闭了,但是另外一端不知道,导致套接字,然后一直在读取,但是读取的长度为 0 --- read 的返回值是 0
read 返回值为 0 把它记作一个特殊条件,当 read 返回值为 0,就认为对方下线,正常服务器是接收到消息,然后去做消息转发 --- 是有顺序的
先收再发 --- 这是一个阻塞过程,但是如果想要连接多个客户端的话,需要频繁调用 accept --- 而 accept 也是阻塞的,对于服务器来说他的两个阻塞来源主要是,read 和 accept