#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方式的更多相关文章

  1. c/c++ 网络编程 单纯http客户端,服务器端

    网络编程 单纯http客户端,服务器端 1,http客户端 2,http服务器端 http客户端: #include <stdio.h> #include <sys/types.h& ...

  2. Linux网络编程10——使用UDP实现五子棋对战

    思路 1. 通信 为了同步双方的棋盘,每当一方在棋盘上落子之后,都需要发送给对方一个msg消息,让对方知道落子位置.msg结构体如下: /* 用于发给对方的信息 */ typedef struct t ...

  3. Python编程-网络编程进阶(IO复用、Socketserver)

    一.认证客户端的链接合法性 如果你想在分布式系统中实现一个简单的客户端链接认证功能,又不像SSL那么复杂,那么利用hmac+加盐的方式来实现. 服务端 from socket import * imp ...

  4. 网络编程API-下 (I/O复用函数)

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

  5. 网络编程:I/O复用

    I/O多路复用是在多线程或多进程编程中常用技术.主要是通过select/epoll/poll三个函数支持的.在此主要对select和epoll函数详细介绍. select函数 该函数运行进程指示内核等 ...

  6. 【Unix网络编程】chapter6 IO复用:select和poll函数

    chapter6 6.1 概述 I/O复用典型使用在下列网络应用场合. (1):当客户处理多个描述符时,必须使用IO复用 (2):一个客户同时处理多个套接字是可能的,不过不叫少见. (3):如果一个T ...

  7. iOS开发——网络编程Swift篇&(六)异步Post方式

    异步Post方式 // MARK: - 异步Post方式 func asynchronousPost() { //创建NSURL对象 var url:NSURL! = NSURL(string: &q ...

  8. UNIX网络编程——epoll 系列函数简介、与select、poll 的区别

    前面博客<<UNIX环境高级编程--epoll函数使用详解>>有关于epoll函数的讲解. 一.epoll 系列函数简介 #include <sys/epoll.h> ...

  9. Linux网络编程之聊天程序(TCP协议之select)

    服务器端:server.c #include <stdio.h> #include <stdlib.h> #include <errno.h> #include & ...

随机推荐

  1. AcWing 850. Dijkstra求最短路 II 堆优化版 优先队列 稀疏图

    //稀疏图 点和边差不多 #include <cstring> #include <iostream> #include <algorithm> #include ...

  2. 【音乐欣赏】《99》 - MOB CHOIR

    曲名:99 作者:MOB CHOIR [00:00.000] 作曲 : 佐々木淳一 [00:00.150] 作词 : 佐々木淳一 [00:00.450] [00:02.370]If everyone ...

  3. Codeforces Round #618 (Div. 1)B(几何,观察规律)

    观察猜测这个图形是中心对称图形是则YES,否则NO #define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> using namespace ...

  4. Go流程结构(for)

    一.程序的流程结构 程序的流程控制结构一共有三种:顺序结构,选择结构,循环结构. 顺序结构:代码从上向下逐行的执行 选择结构:条件满足,某些代码才会被执行.0-1次 if语句,switch语句 循环结 ...

  5. Javascript——(2)DOM

    1.DOM 1)直接寻找 (1)document.getElementById()     //根据ID获取一个标签: (2)   document.getElementsByName()    // ...

  6. Python整合pdf【新手必学】

    在下载课件时往往会分成很多个小的pdf,一个也就几页,想要整合成一整个大pdf,于是百度了一下,网上有很多在线的pdf整合器,但是由于这蛋疼的网速,流量还要花钱,还是想要本地搞. 说python是万能 ...

  7. ES6-对象的简写方式

        var name = 'tom';     var age = 11;     //es5定义对象     var obj = {         name:name,         age ...

  8. nginx 配置Tp5项目时出现 404 Not Found nginx

    1.首先看了nginx报错日志 报 signal process started signal process started表示还有 产生原因 1.可能你的nginx.conf 内容配置的有问题. ...

  9. Vue中修改组件默认样式

    vue 中直接使用 class 修改组件的默认样式,在使用 scoped 之后,样式是没有效果. 此时可以使用div 包裹组件,deep 可以实现修改组件样式 .lxfix /deep/ .contr ...

  10. 测试环境docker-swarm安装部署

    测试环境swarm安装部署 部署前增加监听docker2375端口 centos 增加tcp监听端口 修改/lib/systemd/system/docker.service sed -i ‘s/Ex ...