#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. kill pkill

    首先说一下kill命令,它是通过pid(进程ID)来杀死进程,要得到某个进程的pid,我们可以使用ps(process status)命令,默认情况下,kill命令发送给进程的终止信号是15,但是有些 ...

  2. 1.2 Jmeter 使用代理录制脚本

    参考文档: http://jingyan.baidu.com/article/4e5b3e19333ff191911e2459.html 利用JMeter配置代理:1.添加线程组:  Test Pla ...

  3. java后台接受不到vue传的参数

    @RequestMapping(value = "/delBelowImg") @Transactional public R delBelowFile(@RequestParam ...

  4. Atcoder Beginner Contest153E(完全背包)

    完全背包,价值取题意代价的最小值 #define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> using namespace std; ],b ...

  5. Linux下tail命令的使用方法

    Linux下tail命令的使用方法: linux tail命令用途是依照要求将指定的文件的最后部分输出到标准设备,通常是终端,通俗讲来,就是把某个档案文件的最后几行显示到终端上,假设该档案有更新,ta ...

  6. C++:打开一个文件夹下一系列的文件

    可以用MFC的CFileFind类: FILE *pFile=NULL; CFileFind cff; CString fstr="C:\\page\\*.*"//所以用文件和文件 ...

  7. 6、Java运算符

    运算符的分类 算数运算符 二元运算符 算术运算符中 = - * / % 属于二元运算符,二元运算符指的是需要两个操作数才能完成的运算的运算术. 整数运算规则 1.如果两个操作数有一个为Long,则结果 ...

  8. max=(a>b)?a:b;

    这个函数的意思是如果a>b,max=a:否则max=b. 实际程序: while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Sta ...

  9. Echarts字体和线条颜色设置操作笔记

    在网上偶然看到的一篇文章 感觉不错  下面是原著地址 原著地址:https://blog.csdn.net/eastmount/article/details/52823548

  10. 判断是app 或者 网页

    function openInWebview () { let ua = navigator.userAgent.toLowerCase(); if (ua.match(/MicroMessenger ...