#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. opencv:轮廓逼近与拟合

    轮廓逼近,本质上是减少编码点 拟合圆,生成最相似的圆或椭圆 #include <opencv2/opencv.hpp> #include <iostream> using na ...

  2. opencv:图像边缘发现

    拉普拉斯算子 Mat dst; // ksize 3 ,必须是奇数,不同大小会有不同的效果 Laplacian(src, dst, -1, 3, 1.0, 0, BORDER_DEFAULT); im ...

  3. the MTS failed last time时的解决办法

    关于6.6.3SP2版本提示The MTS failed last time 1.1    发生前提条件 在重启系统 shutdown -r now后,网页打不开,发现MTS服务无法启动,我自己涉及的 ...

  4. go基础_控制语句

    if控制语句 说明:(1)if后面的条件语句不用加括号 (2)if后面可以跟一个简单的初始化语句,并以分号分割,初始化语句中的变量的作用域是整个if语句块 (3)if语句的条件语句需要尽量简单 (4) ...

  5. Python单例

    01. 单例设计模式 设计模式 设计模式 是 前人工作的总结和提炼,通常,被人们广泛流传的设计模式都是针对 某一特定问题 的成熟的解决方案 使用 设计模式 是为了可重用代码.让代码更容易被他人理解.保 ...

  6. (爬虫)随机生成一个header

    #!/usr/bin/env python #-*- coding: utf-8 -*- #__Author__: yunrui #__Version__: 1.0 #__Time__: 2019/1 ...

  7. .net core 框架调用顺序

    API -> AppSrv -> IRepository -> Repository ->

  8. .net core IIS 发布

    发布时注意事项: 1.本机安装.net core SDK 2.启动项目预加载 3.应用池配置为 无托管代码 4.设置应用池-->高级设置-->启动模式为:AlwaysRunning 5.在 ...

  9. ie8无法拉伸背景图

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  10. Python3 post 嵌套json

    目录 python3 post json burpsuite 抓取 python requests 数据包 小结 python3 post json 前些天python3 post出现的小问题做下记录 ...