#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<thread>
#include<mutex>
#include<queue> using namespace std; #define MaxSize 2048 std::queue<int> SocketQueue; /*
tcp多线程并发,非阻塞IO模式,
单线程对socket遍历。
因为设置socket为非阻塞模式,所以能快速读取是否有数据。
*/
void *Task(void *arg)
{
while ()
{
while (SocketQueue.empty())
{
sleep();
} int socket = SocketQueue.front();
SocketQueue.pop(); fd_set rfds, wfds; FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_SET(socket, &rfds);
FD_SET(socket, &wfds);
int selres = select(socket + , &rfds, &wfds, NULL, NULL);
//socket 可读
char msg[MaxSize] = { '\0' };
int len = ;
if ( == FD_ISSET(socket, &rfds))
{ len = recv(socket, msg, MaxSize, );
if (len > )
{
printf("recv %s \n", msg);
}
}
else
{
printf("读取数据还没准备好 !\n");
} //socket 可写
if ( == FD_ISSET(socket, &wfds))
{
if (len > )
{
send(socket, msg, len, );
printf("send %s \n", msg);
}
}
else
{
printf("写数据还没准备好 !\n");
}
len = ;
SocketQueue.push(socket);
} return NULL;
} void Server_Run()
{
unsigned short port = ; printf("TCP Server Started at port %d!\n", port); int sockfd = socket(AF_INET, SOCK_STREAM, );
if (sockfd < )
{
perror("socket");
exit(-);
} struct sockaddr_in my_addr;
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(port);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY); printf("Binding server to port %d\n", port);
int err_log = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr));
if (err_log != )
{
perror("binding");
close(sockfd);
exit(-);
} err_log = listen(sockfd, );
if (err_log != )
{
perror("listen");
close(sockfd);
exit(-);
} printf("Waiting client...\n"); while ()
{
size_t recv_len = ;
struct sockaddr_in client_addr;
char cli_ip[INET_ADDRSTRLEN] = "";
socklen_t cliaddr_len = sizeof(client_addr);
int NewClient;
NewClient = accept(sockfd, (struct sockaddr*)&client_addr, &cliaddr_len);
if (NewClient < )
{
perror("accept");
continue;
} inet_ntop(AF_INET, &client_addr.sin_addr, cli_ip, INET_ADDRSTRLEN);
printf("client ip = %s\n", cli_ip); //设置socket为非阻塞模式。
fcntl(NewClient, F_SETFL, fcntl(NewClient, F_GETFL, ) | O_NONBLOCK);
SocketQueue.push(NewClient);
}
close(sockfd);
} int main()
{
pthread_t thread_id;
pthread_create(&thread_id, NULL, &Task, NULL); Server_Run(); return ;
}

非阻塞IO模型的更多相关文章

  1. 多路复用 阻塞/非阻塞IO模型 网络IO两个阶段

    1.网络IO的两个阶段 waitdata copydata send 先经历:copydata阶段 recv 先经历:waitdata阶段 再经历 copydata阶段 2.阻塞的IO模型 之前写的都 ...

  2. Python之阻塞IO模型与非阻塞IO模型

    Python之阻塞IO模型与非阻塞IO模型 IO模型 1 阻塞IO: 全程阻塞 2 非阻塞IO: 发送多次系统调用: 优点:wait for data时无阻塞 缺点:1 系统调用太多 2 数据不是实时 ...

  3. python 之 并发编程(非阻塞IO模型、I/O多路复用、socketserver的使用)

    9.16 非阻塞IO模型 cpu占用率过高 服务端: from socket import * import time s = socket() s.bind(('127.0.0.1',8080)) ...

  4. IO模型,非阻塞IO模型,select实现多路复用

    1. IO阻塞模型 IO问题: 输入输出 我要一个用户名用来执行登陆操作,问题用户名需要用户输入,输入需要耗时, 如果输入没有完成,后续逻辑无法继续,所以默认的处理方式就是 等 将当前进程阻塞住,切换 ...

  5. NIO【同步非阻塞io模型】关于 NIO socket 的详细总结【Java客户端+Java服务端 + 业务层】【可以客户端间发消息】

    1.前言 以前使用 websocket来实现双向通信,如今深入了解了 NIO 同步非阻塞io模型 , 优势是 处理效率很高,吞吐量巨大,能很快处理大文件,不仅可以 做 文件io操作, 还可以做sock ...

  6. 网络IO模型 非阻塞IO模型

    网络IO模型 非阻塞IO模型 同步 一件事做完后再做另一件事情 异步 同时做多件事情 相对论 多线程 多进程 协程 异步的程序 宏观角度:异步 并发聊天 阻塞IO 阻塞IO的问题 一旦阻塞就不能做其他 ...

  7. python 并发编程 非阻塞IO模型

    非阻塞IO(non-blocking IO) Linux下,可以通过设置socket使其变为non-blocking.当对一个non-blocking socket执行读操作时,流程是这个样子: 从图 ...

  8. NIO【同步非阻塞io模型】关于 文件io 的总结

    1.前言 这一篇随笔是写 NIO 关于文件输入输出的总结 /* 总结: 1.io操作包括 socket io ,file io ; 2.在nio模型,file io使用fileChannel 管道 , ...

  9. python 之网络并发(非阻塞IO模型)

    实现gevent模块 服务端: from socket import * import time s = socket() s.bind(('127.0.0.1',8080)) s.listen(5) ...

随机推荐

  1. Scrapy高级用法

    日志相关 一.日志相关变量 LOG_LEVEL = '' LOG_FILE = '文件名.log' 二.日志级别 5 CRITICAL :严重错误 4 ERROR :普通错误 3 WARNING :警 ...

  2. Mybatis多数据源读写分离(注解实现)

    #### Mybatis多数据源读写分离(注解实现) ------ 首先需要建立两个库进行测试,我这里使用的是master_test和slave_test两个库,两张库都有一张同样的表(偷懒,喜喜), ...

  3. Java方法调用的字节码指令学习

    Java1.8环境下,我们在编写程序时会进行各种方法调用,虚拟机在执行这些调用的时候会用到不同的字节码指令,共有如下五种: invokespecial:调用私有实例方法: invokestatic:调 ...

  4. 使用 Jest 进行 Vue 单元测试

    本文介绍:1.vue-cli3下jest环境的搭建2.vue组件基本的测试方法 环境配置 vue-cli3 的插件使安装流程变得格外简单,通过 vue ui 启动可视化管理系统,在插件栏,点击 ‘添加 ...

  5. selenium-04-验证码问题

    对于web应用来说,大部分的系统在用户登录时都要求用户输入验证码,验证码的类型的很多,有字母数字的,有汉字的,甚至还要用户输入一条算术题的答案的,对于系统来说使用验证码可以有效果的防止采用机器猜测方法 ...

  6. 略学扩展Eculid算法

    扩展 Euclid 算法 Euclid 算法 辗转相除法 计算两个数最大公因数 \(\text{gcd}(a,\,b) = \text{gcd}(b,\,a\%b)\) exEuclid 算法 裴蜀定 ...

  7. mysql 变量赋值的三种方法

    mysql中变量不用事前申明,在用的时候直接用“@变量名”使用就可以了.第一种用法:set @num=1; 或set @num:=1; //这里要使用变量来保存数据,直接使用@num变量第二种用法:s ...

  8. 【SQL】sql查询同一字段相同属性列的值合计

    select  type,sum(value) as valueSum from t group by type

  9. idea中的java web项目(添加jar包介绍)和java maven web项目目录结构

    java web项目 web项目下web根目录名称是可以更改的 idea中新建java web项目,默认src为Sources Root,当然也可以手动改,在Sources Root下右键只能新建Pa ...

  10. SpringBoot第二十五篇:SpringBoot与AOP

    作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/11457867.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言   作者在实际 ...