网络编程
网络编程
最简单socket编程
int sockfd = socket(AF_INET, (struct sockaddr*)&serve_addr, sizeof(struct sockaddr)); |
问题
- 客户端发送时,另外一个客户端不能建立连接
- 断开连接时,循环recv
- 只能连接一次
解决方案
多线程、多进程
- 一个请求一个线程
void *routine(void *arg) {
int connfd = *(int *)arg;
while (1) {
unsigned char buffer[BUFFERSZ] = {0};
int ret = recv(connfd, buffer, BUFFERSZ, 0);
if (ret == 0) {
shutdown(connfd, SHUT_WR);
}
ret = send(connfd, buffer, ret, 0);
}
}
while (1) {
int connfd = accept(sockfd, (struct sockaddr*)&client, &len);
pthread_t thread_id;
pthread_create(&thread_id, NULL, routine, (void*)&connfd);
}IO多路复用
epoll
- epoll本身在内存足够情况下,可以支持100W并发连接
connection
- 逻辑概念
- fd、buffer、callback作为连接的属性,为一对一关系
struct connection { |
Reactor
为什么需要
- 需要存储IO未读完的数据
- 就绪IO占比较少
特点
- 事件驱动:EPOLLIN/EPOLLOUT
- 回调:
- listenfd —-> accept_cb
- clientfd —-> recv_cb
- clientfd —-> send_cb
性能
- 并发量(服务器同时承载的客户端数量)
- QPS:每秒请求数
- 最大时延
- 每秒新建量、建链
- 吞吐量
TCP系统中信息
net.ipv4.ip_local_port_range = 1024 65535 |
网络库封装
- 对Reactor模式的Server进行封装;业务层只需要考虑如何操纵Buffer中的数据
- 网络库内部实现通信机制
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LZY的Code生活!