#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. caffe学习三:使用Faster RCNN训练自己的数据

    本文假设你已经完成了安装,并可以运行demo.py 不会安装且用PASCAL VOC数据集的请看另来两篇博客. caffe学习一:ubuntu16.04下跑Faster R-CNN demo (基于c ...

  2. PTA A1011&A1012

    A1011 World Cup Betting (20 分) 题目内容 With the 2010 FIFA World Cup running, football fans the world ov ...

  3. wrk,ab,locust,Jmeter 压测结果比较

    背景: 项目需要对一批接口进行压测,要求是接口的QPS(Quest Per Second每秒请求数)达到6万以上由于楼主一直使用的压力测试工具是jmeter,但是jmeter单台电脑无法达到6万的QP ...

  4. thinkphp将上传的临时文件移动到指定目录

    thinkphp将上传的临时文件移动到指定目录 新建common.php文件 <?phpuse think\facade\Env; /** 移动上传的临时文件 * * @img_dir stri ...

  5. C++ 函数模板用法

    泛型编程概念:不考虑具体数据类型的编程方式: 函数模板: 1.提供一种特殊的函数可用不同类型进行调用: 2.与普通函数很相似,区别是类型可被参数化: template <typename T&g ...

  6. selenium-04-验证码问题

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

  7. 词向量(one-hot/SVD/NNLM/Word2Vec/GloVe)

    目录 词向量简介 1. 基于one-hot编码的词向量方法 2. 统计语言模型 3. 从分布式表征到SVD分解 3.1 分布式表征(Distribution) 3.2 奇异值分解(SVD) 3.3 基 ...

  8. Django序列化&django REST framework

    第一章.Django序列化操作 1.django的view实现商品列表页(基于View类) # 通过json来序列化,但手写字典key代码量较大,容易出错:还有遇到时间,图片序列化会报错 from g ...

  9. linux&shell学习系列

    1.VMware安装Centos7虚拟机 2.Linux之vim详解 3.linux后台运行的几种方式 4.linux权限管理 5.linux之用户和用户组管理详解 6.grep文本搜索工具详解 7. ...

  10. 【求赐教】VMware workstation 转VSphere

    首先我从其他电脑拷贝过来一台虚拟机(这个说法不知道准不准确,就是把所有文件夹都拷贝过来了),然后打开VMware,通过"打开虚拟机"这个操作,直接找到本地的.vmx文件,如下图所示 ...