C/C++网络编程10——I/O复用服务器端实现select方式
#include <iostream>
#include <cstdlib>
#include <string>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/select.h> using namespace std; #define BUF_SIZE 100 void deal_error(string error_msg)
{
cout << error_msg << endl;
exit();
} int before_socket_accept()
{
int ser_sock = ;
ser_sock = socket(PF_INET, SOCK_STREAM, );
if (ser_sock == -) {
deal_error("socket() failed");
return ser_sock;
} sockaddr_in ser_addr;
ser_addr.sin_family = AF_INET;
ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
ser_addr.sin_port = htons();
if (bind(ser_sock, (sockaddr *)&ser_addr, sizeof(ser_addr)) == -) {
close(ser_sock);
deal_error("bind() failed");
return -;
} if (listen(ser_sock, ) == -) {
close(ser_sock);
deal_error("listen() failed");
return -;
} return ser_sock;
} void accept_connect(int ser_sock)
{
fd_set reads;
FD_ZERO(&reads);
FD_SET(ser_sock, &reads);
int fd_max = ser_sock;
char message[BUF_SIZE]; while(true) {
fd_set cpy_reads = reads;
timeval timeout;
timeout.tv_sec = ;
timeout.tv_usec = ;
int fd_num = select(fd_max + , &cpy_reads, , , &timeout);
if (fd_num == -) {
break;
} else if (fd_num == ) { // select超时返回
continue;
} else { // select监测到有变化
for (int i = ; i < fd_max + ; i++) {
if (FD_ISSET(i, &cpy_reads)) {
if (i == ser_sock) { // 如果是服务器端的套接字描述符发生变化,说明是客户端连接请求(SYN报文)
// 接受客户端的连接请求
sockaddr_in clnt_addr;
socklen_t addr_length = sizeof(clnt_addr);
int clnt_sock = accept(ser_sock, (sockaddr *)&clnt_addr, &addr_length);
FD_SET(clnt_sock, &reads);
if (fd_max < clnt_sock) {
fd_max = clnt_sock;
}
} else { // 接收客户端的数据,并回传给客户端
int str_len = read(i, message, BUF_SIZE);
if (str_len == ) {
FD_CLR(i, &reads);
close(i);
} else {
write(i, message, str_len);
}
}
}
}
}
}
} int main()
{
int ser_sock = before_socket_accept();
if (ser_sock == -) {
return ;
} accept_connect(ser_sock); close(ser_sock);
return ;
}
C/C++网络编程10——I/O复用服务器端实现select方式的更多相关文章
- c/c++ 网络编程 单纯http客户端,服务器端
网络编程 单纯http客户端,服务器端 1,http客户端 2,http服务器端 http客户端: #include <stdio.h> #include <sys/types.h& ...
- Linux网络编程10——使用UDP实现五子棋对战
思路 1. 通信 为了同步双方的棋盘,每当一方在棋盘上落子之后,都需要发送给对方一个msg消息,让对方知道落子位置.msg结构体如下: /* 用于发给对方的信息 */ typedef struct t ...
- Python编程-网络编程进阶(IO复用、Socketserver)
一.认证客户端的链接合法性 如果你想在分布式系统中实现一个简单的客户端链接认证功能,又不像SSL那么复杂,那么利用hmac+加盐的方式来实现. 服务端 from socket import * imp ...
- 网络编程API-下 (I/O复用函数)
IO复用是Linux中的IO模型之中的一个,IO复用就是进程预先告诉内核须要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通过进程进程处理.从而不会在单个IO上堵塞了. Linu ...
- 网络编程:I/O复用
I/O多路复用是在多线程或多进程编程中常用技术.主要是通过select/epoll/poll三个函数支持的.在此主要对select和epoll函数详细介绍. select函数 该函数运行进程指示内核等 ...
- 【Unix网络编程】chapter6 IO复用:select和poll函数
chapter6 6.1 概述 I/O复用典型使用在下列网络应用场合. (1):当客户处理多个描述符时,必须使用IO复用 (2):一个客户同时处理多个套接字是可能的,不过不叫少见. (3):如果一个T ...
- iOS开发——网络编程Swift篇&(六)异步Post方式
异步Post方式 // MARK: - 异步Post方式 func asynchronousPost() { //创建NSURL对象 var url:NSURL! = NSURL(string: &q ...
- UNIX网络编程——epoll 系列函数简介、与select、poll 的区别
前面博客<<UNIX环境高级编程--epoll函数使用详解>>有关于epoll函数的讲解. 一.epoll 系列函数简介 #include <sys/epoll.h> ...
- Linux网络编程之聊天程序(TCP协议之select)
服务器端:server.c #include <stdio.h> #include <stdlib.h> #include <errno.h> #include & ...
随机推荐
- 2019牛客暑期多校训练营(第三场) J LRU management 模拟链表操作
输入n, m,n表示n种操作,m表示最多可以容纳m个串. 第一种操作:先在容器里找是否存在这个串,如果不存在,则添加在末尾,这个串携带了一个值v. 如果存在,则先把之前存在的那个拿出来,然后在后面添加 ...
- Bugku-CTF加密篇之来自宇宙的信号(银河战队出击)
来自宇宙的信号 银河战队出击 flag格式 flag{字母小写}
- Flask的基本使用
最基本的一个Flask模板,实现本地9898端口访问,页面返回hello world from flask import Flask app = Flask(__name__) @app.route( ...
- JQuery选择器(转载)
原文:https://blog.csdn.net/colorapp/article/details/44279645 一. jQuery选择器是什么1. CSS选择器要是某个样式应用于特定的HTML元 ...
- vue音乐播放器
利用vue写一个简单的音乐播放器,包括功能有歌曲搜索.歌曲播放.歌曲封面.歌曲评论.播放动画.mv播放六个功能. <template> <div class="wrap&q ...
- vue中,怎么给data对象添加新的属性?(尼玛这面试题居然让我给碰上了。。。。)
Vue中给data中的对象属性添加一个新的属性时会发生什么,如何解决? 示例: <template> <div> <ul> <li v-for="v ...
- 本地mongodb数据库导出到远程数据库中
把本地Mongodb中的数据导入(批量插入)到服务器的数据库中 1.导出数据: mongoexport -d admin -c users -o outdatafile.dat 选项解释: -d 指明 ...
- C#: switch语句的重构『网摘』
http://bj007.blog.51cto.com/1701577/345100/ switch语句是我们日常工作中最常见也是争论最多的(goto被忽视的前提下).在重构中也把switch语句看成 ...
- Postman如何测试Webservice接口?
一般情况下使用soapui工具测试ws接口,那么能不能使用postman测试呢?当然可以,往下看. 1. 首先请求类型为post 填写上ws地址 ,url地址后不追加?wsdl 2. 设置请求头 he ...
- Linux安装Redis服务
下载:wget http://download.redis.io/releases/redis-5.0.5.tar.gz 解压:tar -zxvf redis-5.0.5.tar.gz 进入redi ...