1.mystery引入

 

   1)Select是一种多路复用IO输入输出模式,在linux的输入输出编程中通过select的轮询机制,发现可用/可读或可写的接口。
   2)低级socket程序中有一个共同点:都是基于阻塞式的编程方式
   3)非阻塞式是函数调用时不阻塞,不管函数执行成功与否,都会立即返回。
   4)优点:程序效率提升
   5)缺点:返回的结果往往是错误的类型码
   6)解决方案:Select机制。


2.实例操

 

1)基于Select模式实现一个网络echo的服务程序,即客户端向服务端发送信息,服务器接收到信息后,再将信息原样转发给客户端
   2)需要设置Select函数
   3)若当前有新连接,则加入到客户端套接字集合,若数量过载,则断开本次连接,并发送提示信息:sorry overload
   4)源代码

//selectsocket.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SERVER_PORT 5555
#define QUEUE_LENGTH 5
#define BUF_SIZE 200
int main(void)
{
int server_socket, new_socket;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
socklen_t sin_size;
int client_socket[QUEUE_LENGTH];
int conn_num;
int yes = 1;
char buf[BUF_SIZE];
int ret;
int i;
if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("socket");
return 0;
}
if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
{
perror("setsockopt");
return 0;
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
memset(server_addr.sin_zero, '\0', sizeof(server_addr.sin_zero));
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
{
perror("bind");
return 0;
}
if (listen(server_socket, 5) == -1)
{
perror("listen");
return 0;
}
printf("listen port %d\n", SERVER_PORT);
fd_set clientfdset;
int maxsock;
struct timeval tv;
conn_num = 0;
sin_size = sizeof(client_addr);
maxsock = server_socket;
while (1)
{
// initialize file descriptor set
FD_ZERO(&clientfdset);
FD_SET(server_socket, &clientfdset);
// timeout setting
tv.tv_sec = 15;
tv.tv_usec = 0;
// add active connection to fd set
for (i = 0; i < QUEUE_LENGTH; i++)
{
if (client_socket[i] != 0)
{
FD_SET(client_socket[i], &clientfdset);
}
}
ret = select(maxsock + 1, &clientfdset, NULL, NULL, &tv);
if (ret < 0)
{
perror("select");
break;
}
else if (ret == 0)
{
printf("waitting timeout\n");
continue;
}
// check every fd in the set
for (i = 0; i < conn_num; i++)
{
if (FD_ISSET(client_socket[i], &clientfdset))
{
ret = recv(client_socket[i], buf, sizeof(buf), 0);
if (ret <= 0)
{
printf("client[%d] close\n", i);
close(client_socket[i]);
FD_CLR(client_socket[i], &clientfdset);
client_socket[i] = 0;
}
else
{
printf("Client[%d] msg:%s\n", i, buf);
send(client_socket[i], buf, sizeof(buf), 0);
}
}
}
if (FD_ISSET(server_socket, &clientfdset))
{
new_socket = accept(server_socket, (struct sockaddr *)&client_addr, &sin_size);
if (new_socket <= 0)
{
perror("accept");
continue;
}
if (conn_num < QUEUE_LENGTH)
{
client_socket[conn_num++] = new_socket;
printf("new client[%d] %s:%d\n", conn_num,
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
if (new_socket > maxsock)
maxsock = new_socket;
}
else
{
send(new_socket, "sorry overload!", sizeof("sorry overload!"), 0);
close(new_socket);
break;
}
}
}
for (i = 0; i < QUEUE_LENGTH; i++)
{
if (client_socket[i] != 0)
{
close(client_socket[i]);
}
}
}

3.mystery注

 

1)设置高级socket属性参数中的应用参数SO_REUSERADDR,实现地址的可重复利用
   2)FD_SET(int fd, fd_set *fdset):向文件描述符集合中增加一个新的文件描述符

3)FD_CLR(int fd, fd_set *fdset):向文件描述符集合中删除一个文件描述符

 
 

【Socket】linux网络多路复用IO技术的更多相关文章

  1. Linux网络编程-IO复用技术

    IO复用是Linux中的IO模型之一,IO复用就是进程预先告诉内核需要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通过进程进程处理,从而不会在单个IO上阻塞了.Linux中,提 ...

  2. linux网络编程 IO多路复用 select epoll

    本文以我的小型聊天室为例,对于服务器端的代码,做了三次改进,我将分别介绍阻塞式IO,select,epoll . 一:阻塞式IO 对于聊天室这种程序,我们最容易想到的是在服务器端accept之后,然后 ...

  3. [转载] Linux下多路复用IO接口 epoll select poll 的区别

    原地址:http://bbs.linuxpk.com/thread-43628-1-1.html 废话不多说,一下是本人学习nginx 的时候总结的一些资料,比较乱,但看完后细细揣摩一下应该就弄明白区 ...

  4. linux网络编程IO模型

    同步与异步:         同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成.         异步是不需要等待被依赖的任务完成,只是通知被依赖的任务要 ...

  5. Linux下多路复用IO接口epoll/select/poll的区别

    select比epoll效率差的原因:select是轮询,epoll是触发式的,所以效率高. Select: 1.Socket数量限制:该模式可操作的Socket数由FD_SETSIZE决定,内核默认 ...

  6. LINUX网络编程 IO 复用

    参考<linux高性能服务器编程> LINUX下处理多个连接时候,仅仅使用多线程和原始socket函数,效率十分低下 于是就出现了selelct poll  epoll等IO复用函数. 这 ...

  7. Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)

    Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...

  8. 转:Linux网络IO并行化技术概览

    转:http://codinginet.com/articles/view/201605-linux_net_parallel?simple=1&from=timeline&isapp ...

  9. Socket网络编程-IO各种概念及多路复用

    Socket网络编程-IO各种概念及多路复用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.操作系统相关知识 1>.同步和异步  函数或方法被调用的时候,调用者是否得到最 ...

随机推荐

  1. tensorflow中的sequence_loss_by_example

    在编写RNN程序时,一个很常见的函数就是sequence_loss_by_example loss = tf.contrib.legacy_seq2seq.sequence_loss_by_examp ...

  2. Android开发环境——SDK相关内容汇总

     Android开发环境将分为SDK相关内容.Eclipse ADT相关内容.模拟器AVD相关内容.调试器DDMS相关内容.日志LogCat相关内容.连接驱动ADB相关内容.内存泄露检测工具MAT相关 ...

  3. RabbitMQ.Client API (.NET)中文文档

    主要的名称空间,接口和类 核心API中定义接口和类 RabbitMQ.Client 名称空间: 1 using RabbitMQ.Client; 核心API接口和类 IModel :表示一个AMQP ...

  4. 一个MVC4 下的验证码用法

    先看一个核心验证码类(不用在意实现过程,直接copy就行),下面包含了两种验证码图片(原理一样),代码如下: using System; using System.Collections.Generi ...

  5. 【MySQL】MySQL的约束

    在开始之前,笔者介绍一下笔者使用的数据库版本为5.7.所有的关系型数据库都支持对数据表使用约束,通过约束可以更好的保证数据表里数据的完整性.约束是在表上强制执行的数据校验,约束主要用于保证数据库里数据 ...

  6. xcode9报错 Safe Area Layout Guide before iOS9.0

    运行工程的时候会遇到  Safe Area Layout Guide before iOS9.0 这是因为xcode9  storyboard的设置里面多了 个 Safe Area Layout Gu ...

  7. .net core 实现默认图片

    web 上 如果图片不存在 一般是打xx  这时候 一般都是会设置默认的图片 代替   现在用中间件的方式实现统一设置   一次设置 全部作用 .net core 实现默认图片 Startup 文件 ...

  8. Android Studio:正确导入SO相关文件

      导入so文件有2种方式 第一种: 使用jniLibs文件夹导入so文件,则仅需将所有cpu类型的文件夹拷进去. 在project结构下,module目录下创建libs文件夹,放入jar文件:在sr ...

  9. 【转】TeXmacs:一个真正“所见即所得”的排版系统

    TeXmacs:一个真正“所见即所得”的排版系统 好久没有推荐过自己喜欢的软件了,现在推荐一款我在美国做数学作业的私家法宝:TeXmacs.我恐怕不可能跟以前那么有闲心写个长篇的 TeXmacs 说明 ...

  10. Linux 性能測试工具

    Linux 性能測试工具 linux performance 查看系统配置 查看CPU信息 lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64- ...