Linux网络编程——tcp并发服务器(poll实现)
想详细彻底地了解poll或看懂下面的代码请参考《Linux网络编程——I/O复用之poll函数》
代码:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <poll.h>
#include <errno.h>
#define OPEN_MAX 100 int main(int argc, char *argv[])
{
//1.创建tcp监听套接字
int sockfd = socket(AF_INET, SOCK_STREAM, ); //2.绑定sockfd
struct sockaddr_in my_addr;
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons();
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)); //3.监听listen
listen(sockfd, ); //4.poll相应参数准备
struct pollfd client[OPEN_MAX];
int i = , maxi = ;
for(;i<OPEN_MAX; i++)
client[i].fd = -;//初始化poll结构中的文件描述符fd client[].fd = sockfd;//需要监测的描述符
client[].events = POLLIN;//普通或优先级带数据可读 //5.对已连接的客户端的数据处理
while()
{
int ret = poll(client, maxi+, -);//对加入poll结构体数组所有元素进行监测 //5.1监测sockfd(监听套接字)是否存在连接
if((client[].revents & POLLIN) == POLLIN )
{
struct sockaddr_in cli_addr;
int clilen = sizeof(cli_addr);
int connfd = ;
//5.1.1 从tcp完成连接中提取客户端
connfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen); //5.1.2 将提取到的connfd放入poll结构体数组中,以便于poll函数监测
for(i=; i<OPEN_MAX; i++)
{
if(client[i].fd < )
{
client[i].fd = connfd;
client[i].events = POLLIN;
break;
}
} //5.1.3 maxi更新
if(i > maxi)
maxi = i; //5.1.4 如果没有就绪的描述符,就继续poll监测,否则继续向下看
if(--ret <= )
continue;
} //5.2继续响应就绪的描述符
for(i=; i<=maxi; i++)
{
if(client[i].fd < )
continue; if(client[i].revents & (POLLIN | POLLERR))
{
int len = ;
char buf[] = ""; //5.2.1接受客户端数据
if((len = recv(client[i].fd, buf, sizeof(buf), )) < )
{
if(errno == ECONNRESET)//tcp连接超时、RST
{
close(client[i].fd);
client[i].fd = -;
}
else
perror("read error:"); }
else if(len == )//客户端关闭连接
{
close(client[i].fd);
client[i].fd = -;
}
else//正常接收到服务器的数据
send(client[i].fd, buf, len, ); //5.2.2所有的就绪描述符处理完了,就退出当前的for循环,继续poll监测
if(--ret <= )
break; }
}
}
return ;
}
Linux网络编程——tcp并发服务器(poll实现)的更多相关文章
- Linux 网络编程——TCP
环境:Linux C 一.协议介绍 TCP是面向连接的协议,提供可靠的数据传输:TCP协议的可靠传输基于三次握手.四次挥手以及确认重传机制实现.下面来具体展示下TCP的三次握手.四次挥 ...
- Linux网络编程-tcp缓存设置
最近发现服务的逻辑完成时间很短,但是上游接收到的时间比较长,所以就怀疑是底层数据的序列化/反序列化.读写.传输有问题,然后怀疑是TCP的读写缓存是不是设置太小.现在就记录下TCP缓存的各配置项以及缓存 ...
- Linux网络编程:客户端/服务器的简单实现
一. Socket的基本知识 1. socket功能 Socket层次 Socket实质上提供了进程通信的端点,进程通信之前,双方必须首先各自创建一个端点,否则是没有办法建立联系并相互通信的. 每一个 ...
- UNIX网络编程---TCP客户/服务器程序示例(五)
一.概述 客户从标准输入读入一行文本,并写给服务器 服务器从网络输入读入这行文本,并回射给客户 客户从网络输入读入这行回射文本,并显示在标准输出上 二.TCP回射服务器程序:main函数 这里给了函数 ...
- Linux网络编程echo多线程服务器
echo_server服务器多线程版本 #include <unistd.h> #include <stdlib.h> #include <stdio.h> #in ...
- linux网络编程echo多进程服务器
echo_server 多进程版本 #include <unistd.h> #include <stdlib.h> #include <stdio.h> #incl ...
- 3.网络编程-tcp的服务器简单实现
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2019/1/13 22:03 # @Author : ChenAdong # @ema ...
- linux网络编程tcp
之前学习的时候笔记没有保存好,这次重新编写一个案例. 客户端实现程序代码: #include <string.h> #include <stdlib.h> #include & ...
- Linux网络编程学习路线
转载自:https://blog.csdn.net/lianghe_work/article 一.网络应用层编程 1.Linux网络编程01——网络协议入门 2.Linux网络编程02——无连接和 ...
随机推荐
- 面向过程编程实例------grep-rl 'root 路径
#应用:grep -rl 'root' /etc import os def deco(func): def wrapper(*args): g=func(*args) next(g) return ...
- Linux进程中TIME_OUT解析
TIMEWAIT状态本身和应用层的客户端或者服务器是没有关系的.仅仅是主动关闭的一方,在使用FIN|ACK|FIN|ACK四分组正常关闭TCP连接的时候会出现这个TIMEWAIT.服务器在处理客户端请 ...
- 封装一个既能遍历数组又能遍历对象的的forEach函数
function newforEach(obj,fn) { var key; if(obj instanceof Array){ obj.forEach(function(item,index){ f ...
- php数组函数-array_intersect()
array_intersect()函数返回两个或多个数组的交集数组 结果数组包含了所有在被比较数组中,也同时出现在所有其他参数数组中 的值,键名保留不变 array_intersect(array1, ...
- linux下安装jsp开发运行环境(centos7)
1 开发环境包括 1)apache-tomcat 2)java-jdk 3)mysql 2 apache-tomcat安装(应该先装java再装tomcat) 1)到官网下载最新版本(不建议用yum安 ...
- .NET CORE 动态调用泛型方法
using System; using System.Reflection; namespace DynamicCall { class Program { static void Main(stri ...
- 微信小程序与微信公众号同一用户登录问题
微信小程序与微信公众号同一用户登录问题 最近在做微信小程序与微信公众号登录合并的接口.整理相关资料以及个人认识的心得写了这篇文章与大家一起分享. 首先,简单说下我遇到的问题是我们的程序调用微信小程序得 ...
- 深入剖析JDK动态代理源码实现
动态代理.静态代理优缺点优点:业务类只需要关注业务逻辑本身,保证了业务类的重用性.这是代理的共有优点.动态代理只有在用到被代理对象的时候才会对被代理类进行类加载. 而静态代理在编译器就已经开始占内存了 ...
- JavaWeb -- 内省—beanutils工具包 的使用
Apache组织开发了一套用于操作JavaBean的API,这套API考虑到了很多实际开发中的应用场景,因此在实际开发中很多程序员使用这套API操作JavaBean,以简化程序代码的编写. Beanu ...
- Python之面向对象总结
一.面向对象 1.面向过程 a.优点:极大的降低了写程序的复杂度,只需要顺着执行的步骤,堆叠代码即可 b.缺点:一套流水线或者流程就是来解决一个问题,代码就是牵一发而东莞全身 2.面向对象 a.优点: ...