io多路复用___select
发布日期:2021-05-15 09:23:36 浏览次数: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; }

上一篇:UDP server/client实例
下一篇:基于C的socket编程实现linux虚拟机和windows传输文件(图片)

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2025年04月11日 07时32分47秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章