博客
关于我
io多路复用___select
阅读量:593 次
发布时间:2019-03-12

本文共 2430 字,大约阅读时间需要 8 分钟。

#include #include #include #include #include #include #define SIZE 30 int tcp_socket(int port);int main(int argc, char *argv[]) {if (argc != 2) {printf("请提供端口号\n");return 1;}int sock = tcp_socket(atoi(argv[1]));if (sock == -1) {printf("创建socket失败\n");return 1;}int r;fd_set reads;int temp;socklen_t len;int fd_max;struct timeval timeout;char buf[SIZE]; FD_ZERO(&reads);FD_SET(sock, &reads);fd_max = sock;struct sockaddr_in cli_addr;while (1) {    temp = reads; // 创建临时集合保存原状态    timeout.tv_sec = 5; // 设置超时时间    timeout.tv_usec = 0;    r = select(fd_max + 1, &temp, NULL, NULL, &timeout);    if (r == -1) break;    else if (r == 0) {        printf("连接超时\n");        continue;    } else {        for (int i = 3; i < fd_max + 1; i++) { // 从3开始检查其他fd            if (FD_ISSET(i, &temp)) { // 检查是否有变化                if (i == sock) { // 有新客户端连接                    len = sizeof(cli_addr);                    int cli_sock = accept(sock, (struct sockaddr *)&cli_addr, &len);                    if (cli_sock == -1) continue;                    FD_SET(cli_sock, &reads);                    if (fd_max < cli_sock) {                        fd_max = cli_sock;                    }                    printf("收到新连接:%d\n", cli_sock);                } else { // 有客户端向服务器发送数据                    memset(buf, 0, SIZE);                    r = read(i, buf, SIZE - 1);                    if (r == 0) { // 客户端断开连接                        FD_CLR(i, &reads);                        close(i);                        printf("客户端 %d 断开连接\n", i);                    } else if (r > 0) {                        buf[r] = '\0';                        printf("从客户端 %d 收到消息:%s\n", i, buf);                        write(i, buf, r); // 将消息发送回客户端                    } else {                        printf("读取数据错误\n");                        exit(1);                    }                }            }        }    }}close(sock);return 0; } int tcp_socket(int port) {int sock;struct sockaddr_in addr;sock = socket(AF_INET, SOCK_STREAM, 0);if (sock == -1) return -1; // 设置端口复用const int on = 1;if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on))) {    printf("设置端口复用失败\n");    return -1;}memset(&addr, 0, sizeof(addr));addr.sin_family = AF_INET;addr.sin_addr.s_addr = htonl(INADDR_ANY);addr.sin_port = htons(port);int r = bind(sock, (struct sockaddr *)&addr, sizeof(addr));if (r == -1) return -1;r = listen(sock, 10);if (r == -1) return -1;return sock; }

转载地址:http://gznxz.baihongyu.com/

你可能感兴趣的文章
【Flink】Flink 底层RPC框架分析
查看>>
MySQL错误日志(Error Log)
查看>>
解决:angularjs radio默认选中失效问题
查看>>
windows环境下安装zookeeper(仅本地使用)
查看>>
缓冲区溢出实例(一)--Windows
查看>>
Python中字符串前添加r ,b, u, f前缀的含义
查看>>
Hadoop学习笔记—Yarn
查看>>
JSONPath小试牛刀之Snack3
查看>>
Jenkins - 部署在Tomcat容器里的Jenkins,提示“反向代理设置有误”
查看>>
wxWidgets源码分析(3) - 消息映射表
查看>>
wxWidgets源码分析(5) - 窗口管理
查看>>
wxWidgets源码分析(7) - 窗口尺寸
查看>>
wxWidgets源码分析(8) - MVC架构
查看>>
wxWidgets源码分析(9) - wxString
查看>>
[白话解析] 深入浅出熵的概念 & 决策树之ID3算法
查看>>
[梁山好汉说IT] 梁山好汉和抢劫银行
查看>>
[源码解析] 消息队列 Kombu 之 基本架构
查看>>
[源码分析] 消息队列 Kombu 之 启动过程
查看>>
[源码分析] 消息队列 Kombu 之 Consumer
查看>>
抉择之苦
查看>>