TCP协议的客户端和服务端的多路复用

news/2024/9/30 23:38:03

img

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/select.h> 
int main(void)
{
     //1.创建套接字
    int  sockfd  = socket(AF_INET, SOCK_STREAM, 0);
    if( sockfd < 0)
    {
        perror("socket");
        return -1;
    }
     //2.绑定端口和地址
    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_port = htons(9527);
     //转网络字节序
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    //绑定地址为INADDR_ANY,这个个服务器程序在那个ip地址上运行就绑定那个ip地址    
    int ret = bind(sockfd, (struct sockaddr*)&addr,sizeof(addr));
    if(ret < 0)
    {
        perror("bind");
        return -1;
    }
    //3.监听
    ret  = listen(sockfd, 4);
    if(ret < 0)
    {
        perror("listen");
        return -1;
    }
     //接受连接--accept阻塞
    //接收客户端数据--recv阻塞
     //select多路复用
     fd_set readfds;
     //定义读文件描述符集合
    int  cfds[50]={0};
     //保存所有客户端的套接字
    while(1)
    {
        int maxfd = sockfd;
        //清空集合
        FD_ZERO(&readfds);
        FD_SET(sockfd,&readfds);
          //把sockfd添加到readfds集合中
          //把客户端的套接字也添加到集合中
        for(int i=0; i<50; i++)
        {
           if(cfds[i] != 0)//如果不等于0就说明这个空间存储了套接字 
           {
                FD_SET(cfds[i],&readfds);
                maxfd = maxfd>cfds[i]?maxfd:cfds[i];
            }
        }        //select用监听readfds里面的所有文件描述符,
        //如果某一个或多个描述符有响应就跳出select函数
        ret = select(maxfd+1,&readfds,NULL, NULL, NULL);
        if(ret < 0)
        {
            perror("select");
        }
        //判断是否是sockfd有数据---说明有客户端连接
        if(FD_ISSET(sockfd, &readfds))
        { 
               //接受连接
            int clientfd = accept(sockfd, NULL,NULL);
            if(clientfd < 0)
            {
                perror("accept");
            }            //把客户端套接字保存到cfds数组中
            for(int i=0; i<50; i++)
            {
                if(cfds[i] == 0)//判断放在没有使用的空间中
                {
                     cfds[i] = clientfd;
                     break;
                }
            }
         }        //判断是否是客户端有数据
        for(int i=0; i<50; i++)
        {
            //判断套接字是否存在,并且是否有数据到达
            if(cfds[i] != 0 && FD_ISSET(cfds[i], &readfds))
            { 
                     //接收客户端数据
                char buffer[128]={0};
                int size = recv(cfds[i], buffer, 128, 0);
                if(size<=0)
                {
                    printf("有客户端掉线\n");
                    close(cfds[i]);
                    cfds[i] = 0;
                }
                //把接收到的信息转发给客户端自己
                     size = send(cfds[i],buffer,size,0);            }
        }
    }
     printf("有客户端连接\n");
    close(sockfd);
 }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hjln.cn/news/45100.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Web应用课 第四讲 内外边距、盒子模型、位置、浮动、名片实战

内外边距 margin 内边距 margin属性为给定元素设置所有四个(上下左右)方向的外边距属性。 可以接受1~4个值(上、右、下、左的顺序) 可以分别指明四个方向:margin-top、margin-right、margin-bottom、margin-left 取值 length:固定值 percentage:相对于包含块的宽度,以百…

红日复现为什么失败之struct漏洞复现

struts2漏洞 一、指纹识别 s2的url路径组成(详见struts.xml配置文件):name工程名+namespace命名空间+atcion名称+extends拓展名部署在根目录下,工程名可为空;当然namespace名称也可设置为空;拓展名也可设置为空。 方法一 (1)url会有.action或.do后缀文件名(eg:http://…

使用getaddrinfo函数来获取并打印出www.baidu.com的所有IP地址(IPv4和IPv6)

#include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h>int main() {struct addrinfo hints, *res, *p;int status;char ipstr[INET6_ADDRSTRLEN];// 设置h…

C138 线段树分治 P2056 [ZJOI2007] 捉迷藏

视频链接:C138 线段树分治 P2056 [ZJOI2007] 捉迷藏_哔哩哔哩_bilibili P2056 [ZJOI2007] 捉迷藏 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)// 线段树分治 O(nlognlogn) #include <iostream> #include <cstring> #include <algorithm> #include <…

[lnsyoj118/luoguP3369]普通平衡树

平衡树 Treap题意 维护一个数据结构,要求支持插入,删除,根据排名查数,根据数查排名,查询前驱,查询后继\(6\)个操作 sol 考虑到后四个查询的操作,会发现使用二叉搜索树(BST)完全可以实现 为了完成这四个操作,需要在每个节点记录\(3\)个值:\(key\) 表示当前节点的数 \(c…

牛客周赛46(思路待补)

比赛链接:牛客周赛46赛时感受 本场参加的是内测,多亏了内测群的佬提供的思路,得以AK。 ABC都是简单的签到题,D稍微需要分类一下,EF有点算法知识,E可以使用前缀和+二分搜索过掉,但是听说好像还能使用离散化树状数组等等,F是数学知识,隔板法和求质数、求组合…

[TinyRenderer] Chapter1 p3 Line

(注:本小节不是对划线算法事无巨细的证明,如果你需要更加系统的学习,请跳转至文末的参考部分) 如果你是一名曾经学习过图形学基础的学生,那么你一定对画线算法稔熟于心,中点划线算法,Bresenham算法。其中,现代光栅化器中使用最多的就是Bresenham算法,它以去除了除法和…

3个月搞定计算机二级C语言!高效刷题系列进行中

前言 大家好,我是梁国庆。 计算机二级应该是每一位大学生的必修课,相信很多同学的大学flag中都会有它的身影。 我在大学里也不止一次的想要考计算机二级office,但由于种种原因,备考了几次都不了了之。 这一次我想换个目标! 备考计算机二级C语言 今天山东省考试院发布了关于…