select函数

来源:互联网 发布:mac地址 ip地址区别 编辑:程序博客网 时间:2024/06/16 01:14
//服务器程序//(1)当fork字进程时,必须捕获SIGCHLD信号//(2)当捕获信号时,必须处理被中断的系统调用(accept)//(3)SIGCHLD的信号处理函数必须被正确的书写,应使用waitpid函数,以免留下僵尸进程#include<stdio.h>#include<stdlib.h>#include<strings.h>#include<string.h>#include<netinet/in.h>#include<sys/socket.h>#include<signal.h>#include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<errno.h>void sig_chld(int signo)//信号处理函数必须要有一个int 型的参数,并且返回值为void{    pid_t pid;    int stat;    while((pid = waitpid(-1, &stat, WNOHANG)) > 0)    {        printf("child %d terminated\n", pid);    }    return;}void str_echo(int sockfd){    char buffer[100];    int n;    memset(buffer, 0, 100);    while((n = read(sockfd, buffer, 100)) > 0)    {        buffer[n+1]='\0';        printf("%s\n", buffer);        write(sockfd, buffer, strlen(buffer));        memset(buffer, 0, 100);    }}int main(){    int listenfd, connfd;//监听套接字、已连接的套接字    struct sockaddr_in server_sockaddr, client_sockaddr;//IPv4套接字地址结构    socklen_t clilen;    pid_t pid;    if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)    {        fprintf(stderr, "Socket failed\n");        exit(EXIT_FAILURE);    }    bzero(&server_sockaddr, sizeof(server_sockaddr));//清零    server_sockaddr.sin_family = AF_INET;    server_sockaddr.sin_port = htons(9877);//以网络字节序存储本地端口号    server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);//通配地址      if(bind(listenfd, (struct sockaddr*)&server_sockaddr, sizeof(server_sockaddr)) == -1)//绑定本地地址和端口号    {        fprintf(stderr, "Bind failed\n");        exit(EXIT_FAILURE);    }    if(listen(listenfd, 5) == -1)    {        fprintf(stderr, "Listen failed\n");        exit(EXIT_FAILURE);    }    signal(SIGCHLD, sig_chld);//信号接收函数    while(1)    {        clilen = sizeof(client_sockaddr);        if((connfd = accept(listenfd, (struct sockaddr*)&client_sockaddr, &clilen)) < 0)        {            if(errno == EINTR)                continue;            else            {                fprintf(stderr, "Accept failed\n");                exit(EXIT_FAILURE);            }        }        //创建子进程处理客户端的请求        if((pid = fork()) == 0)//子进程中去处理客户端的服务        {            close(listenfd);            str_echo(connfd);            close(connfd);            exit(0);        }        close(connfd);    }}
//一个客户端连接多个服务器#include<stdio.h>#include<stdlib.h>#include<strings.h>#include<string.h>#include<netinet/in.h>#include<sys/socket.h>#include<arpa/inet.h>#include<sys/select.h>//select 函数#include<sys/time.h>//包含struct timeval结构#include<sys/types.h>//#include<sys/stats.h>int max(int fd1, int fd2){    return fd1>fd2?fd1:fd2;}void str_cli(int sockfd){//  char send_buffer[100], receive_buffer[100];//  int n;//  memset(send_buffer, 0, 100);//  memset(receive_buffer, 0, 100);//  while(fgets(send_buffer, 100, stdin) != NULL)//  {//      write(sockfd, send_buffer, strlen(send_buffer));//向网络中发数据//      read(sockfd, receive_buffer, 100);//      printf("%s\n", receive_buffer);//      memset(send_buffer, 0, 100);//      memset(receive_buffer, 0, 100);//  }    int maxfdp1;//指定待测试的描述符的个数    fd_set rset;//描述符集    char send_buffer[100], receive_buffer[100];    FD_ZERO(&rset);//描述符清零    memset(send_buffer, 0, 100);    memset(receive_buffer, 0, 100);//清零两个数组    while(1)    {        FD_SET(fileno(stdin), &rset);//把文件流指针转化为文件描述符,fileno被包含在stdio中        FD_SET(sockfd, &rset);        maxfdp1 = max(fileno(stdin), sockfd) + 1;//该值为最大的文件描述符加1,因为文件描述符的是从0开始的        select(maxfdp1,  &rset, NULL, NULL, NULL);        if(FD_ISSET(sockfd, &rset))//使用FD_ISZET检测有没有就绪        {            if(read(sockfd, receive_buffer, 100) == 0)            {                fprintf(stderr, "server terminated prematurely");                exit(EXIT_FAILURE);            }            //fputs(receive_buffer, stdout)            printf("%s\n", receive_buffer);            memset(receive_buffer, 0, 100);        }        if(FD_ISSET(fileno(stdin), &rset))        {            if(fgets(send_buffer, 100, stdin) == NULL)                    return;            write(sockfd, send_buffer, strlen(send_buffer));            memset(send_buffer, 0, 100);        }    }}int main(int argc, char **argv){    int sockfd[5], i;//套接字描述符    struct sockaddr_in server_sockaddr;//需要连接服务器的地址    if(argc != 2)    {        fprintf(stderr, "Input error\n");        exit(EXIT_FAILURE);    }    for(i=0; i<5; i++)    {        if((sockfd[i] = socket(AF_INET, SOCK_STREAM, 0)) == -1)        {            fprintf(stderr, "Socket failed\n");            exit(EXIT_FAILURE);        }        bzero(&server_sockaddr, sizeof(server_sockaddr));//清零        server_sockaddr.sin_family = AF_INET;        server_sockaddr.sin_port = htons(9877);//以网络字节序存储端口号        inet_pton(AF_INET, argv[1], &server_sockaddr.sin_addr);//将字符串转化为以网路字节序存储的地址        if(connect(sockfd[i], (struct sockaddr*)&server_sockaddr, sizeof(server_sockaddr)) == -1)//连接        {            fprintf(stderr, "Connec failed\n");        }    }    str_cli(sockfd[0]);//从套接字中读写数据    exit(0);}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 绝地求生号被盗了邮箱被改了怎么办 微信邮箱怎么接收不到验证码怎么办 要申请一个特定的qq邮箱号怎么办 中银e贷额度为0怎么办 中银e贷被冻结了怎么办 中国银行e贷款填错了被拒怎么办 中银e贷逾期2天怎么办 大学生助学贷款网站密码忘了怎么办 乳晕毛囊挤压捏起来有小硬节怎么办 手机版模拟人生孕妇任务卡死怎么办 百度网盘的表格没保存怎么办 爱奇艺买的会员不小心删了怎么办 多次举报和拉黑克隆不了好友怎么办 货车把货拉到货主不付钱怎么办 中国银行网银公司用户名忘了怎么办 伟星管网站查不到电水管图纸怎么办 我的耕地己确权被他人侵权怎么办 掌上川电登录密码忘记了怎么办 华为商城不小心点了确认收货怎么办 买的认证服务号没有微信支付怎么办 手机微信里的外网链接打不开怎么办 微信违规无法加入群聊怎么办 苹果手机微信储存空间不足怎么办 拼多多砍价砍不到0元怎么办 妻子婚内出轨我的熟人怎么办 父亲怀疑母亲有外遇作为儿子怎么办 老婆出轨我总心理过不去坎该怎么办 失业人员离培训机构远了怎么办 遇到申请假冒商品的仅退款怎么办 微信被骗什么消息都不知道怎么办 微信用手机登录显示未注册怎么办 唯品会海淘订单取消不了怎么办 大排量摩托芯片钥匙断了怎么办 夏天太热在宿舍没空调怎么办? 汽车钥匙掉了怎么办半路到不了家 当顾客说产品太贵的时候 怎么办 邮件还没有下载被发送者删除怎么办 绝地求生号被盗了怎么办邮箱没有用 暴雪忘了密码换了手机号怎么办 华为荣耀10看电视缓冲太慢怎么办 交易猫梦幻西游手游恶意仲裁怎么办