【Linux】Socket编程TCP
TCP socket API 详解
回顾程序中用到的socket API函数:
socket()
- 对于IPv4,family参数指定为AF_INET
- 对于TCP协议,type参数指定为SOCK_STREAM,表示面向流的传输协议
bind()
- 服务器程序所监听的网络地址和端口号通常是固定不变的,客户端程序得知服务器程序的地址和端 口号后就可以向服务器发起连接
- 服务器需要调用bind绑定一个固定的网络地址和端口号
- bind()成功返回0,失败返回-1
- bind()的作用是将参数sockfd和myaddr绑定在一起,使sockfd这个用于网络通讯的文件描述符监听myaddr所描述的地址和端口号
- 因为struct sockaddr *是一个通用指针类型,myaddr参数实际上可以接受多种协议的sockaddr结构体,而它们的长度各不相同,所以需要第三个参数addrlen指定结构体的长度
- 多线程 TCPServer.hpp
listen()
- listen()声明sockfd处于监听状态,并且最多允许有backlog个客户端处于连接等待状态,如果接收 到更多的连接请求就忽略,设置不会太大(一般是5)
- listen()成功返回0,失败返回-1
accept()![]()
- 如果服务器调用accept()时还没有客户端的连接请求,就阻塞等待直到有客户端连接上来
- addr是一个传出参数,accept()返回时传出客户端的地址和端口号
- 如果给addr参数传NULL,表示不关心客户端的地址
- addrlen参数是一个传入传出参数(value-result argument),传入的是调用者提供的,缓冲区addr 的c长度以避免缓冲区溢出问题,传出的是客⼾端地址结构体的实际长度
connect()
- 客户端需要调用connect()连接服务器
- connect和bind的参数形式一致,区别在于bind的参数是自己的地址,而connect的参数是对放的地址
1. V1 - Echo Server
思路:
根据实现发现由于:
- 当启动一个客户端后再启动一个客户端,尝试连接服务器,发现第二个客户端不能正确的和服务器进行通信
- 分析原因,是因为我们 accecpt 了一个请求之后,就在一直 while 循环尝试 read ,没有继续调用accecpt ,导致不能接受新的请求
- 所所以单进程版本的TCP ,只能处理一个连接,这是不科学的
2. V2 - Echo Server多进程版本
思路:
代码实现:
TCP实现客户端echo 单进程+多进程版
3. V3 - Echo Server多线程版本
思路:
代码:
TCP多线程版本代码
4. V3-1 - 多线程远程命令执行
Command.hpp:命令类,⽤来执行命令,并获取结果
代码:
多线程远程命令执行
5. V4 - Echo Server 线程池版本
引入系统部分的线程池,进行简单的业务处理
代码:
线程池版本实现
