• 实现socket非阻塞设置


    刚开始学习,难免有些疏漏之处,请各位多多指教。

    程序亲测可以使用。废话不多说。

    网络IO模型分为阻塞IO、非阻塞IO、异步IO、IO复用、信号驱动IO。

    阻塞IO: 有数据时,直接读;没有数据时,等待读。

    非阻塞IO: 无论内核有没有数据都读。

    以下是程序:

    1. serevr.c

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include <unistd.h>
      5 
      6 #include <sys/types.h>    
      7 #include <sys/socket.h>
      8 #include <netinet/in.h>
      9 #include <arpa/inet.h>
     10 #include <sys/stat.h>
     11 #include <fcntl.h>
     12 
     13 
     14 
     15 #define PORT 4455
     16 #define MAX_LEN 5
     17 
     18 //1. 初始化socket  -  tcp
     19 int init_socket()
     20 {
     21     //1-1. socket
     22     int sfd = socket(AF_INET,SOCK_STREAM,0);
     23     if(sfd == -1)
     24     {
     25         perror("socket");
     26         exit(1);
     27     }
     28     //1-2 REUSEADDR
     29     int val = 1;
     30     int ret = setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,(void *)&val,sizeof(val));
     31     if(ret == -1)
     32     {
     33         perror("setsockopt");
     34         exit(1);
     35     }
     36     // 1-3 bind
     37     struct sockaddr_in saddr;
     38     saddr.sin_family = AF_INET;
     39     saddr.sin_addr.s_addr = INADDR_ANY;
     40     saddr.sin_port = htons(PORT); 
     41     ret = bind(sfd,(struct sockaddr *)&saddr,sizeof(saddr));
     42     if(ret == -1)
     43     {
     44         perror("bind");
     45         exit(1);
     46     }
     47     // 1-4 listen
     48     ret = listen(sfd,MAX_LEN);
     49     if( ret == -1)
     50     {
     51         perror("listen");
     52         exit(1);
     53     }
     54     
     55     printf("Srever is ready ...
    ");
     56     return sfd;
     57 }
     58 //2. 处理接收,设置为非阻塞型的
     59 int deal_accept(int sfd)
     60 {
     61     // 2-1 accept
     62     int cfd = accept(sfd,NULL,NULL);
     63     if(cfd == -1)
     64     {
     65         perror("accept");
     66         exit(1);
     67     }
     68     // 2-2 获得cfd属性
     69     int flags = fcntl(cfd,F_GETFL);
     70     if(flags == -1)
     71     {
     72         perror("fcntl F_GETFL");
     73         exit(1);
     74     }
     75     // 2-2 判断flags是否具有O_NONBLOCK属性
     76     if(!(flags&O_NONBLOCK))
     77     {
     78         flags |= O_NONBLOCK;
     79         int ret = fcntl(cfd,F_SETFL,flags);
     80         if(ret == -1)
     81         {
     82             perror("fcntl F_SETFL");
     83             exit(1);
     84         }
     85     }
     86     return cfd;
     87 }
     88 
     89 void deal_communication(int cfd)
     90 {
     91     char buf[64] = {''};
     92     while(1)
     93     {
     94         memset(buf,'',sizeof(buf));
     95         recv(cfd,buf,sizeof(buf),0);
     96         printf("client say : %s
    ",buf);
     97         if(strncmp(buf,"quit",4) == 0)  break;
     98         sleep(3);
     99     }
    100     return ;
    101 }
    102 
    103 int main()
    104 {
    105     //1. 初始化socket  -  tcp
    106     int sfd = init_socket();
    107     //2. 处理接收,设置为非阻塞型的
    108     int cfd = deal_accept(sfd);
    109     //3. 通信
    110     deal_communication(cfd);
    111     return 0;
    112 }

    2. client.c

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 #include <unistd.h>
     5 
     6 #include <sys/types.h>    
     7 #include <sys/socket.h>
     8 #include <netinet/in.h>
     9 #include <arpa/inet.h>
    10 #include <sys/stat.h>
    11 #include <fcntl.h>
    12 
    13 
    14 #define IP "127.0.0.1"
    15 #define PORT 4455
    16 //1. 初始化socket
    17 int init_socket()
    18 {
    19     // 1-1 socket
    20     int sfd = socket(AF_INET,SOCK_STREAM,0);
    21     if(-1 == sfd )
    22     {
    23         perror("socket");
    24         exit(1);
    25     }
    26     // 1-2 connect
    27     struct sockaddr_in saddr;
    28     saddr.sin_family = AF_INET;
    29     saddr.sin_addr.s_addr = inet_addr(IP);
    30     saddr.sin_port = htons(PORT);
    31     int  ret = connect(sfd,(struct sockaddr *)&saddr,sizeof(saddr));
    32     if(-1 == ret )
    33     {
    34         perror("connect");
    35         exit(1);
    36     }
    37     
    38     return sfd;
    39 }
    40 
    41 void deal_communication(int sfd)
    42 {
    43     char buf[64] = {''};
    44     while(1)
    45     {
    46         memset(buf,'',sizeof(buf));
    47         printf("请输入:");
    48         scanf("%s",buf);
    49         send(sfd,buf,strlen(buf),0);
    50         printf("client say :%s
    ",buf);
    51         if(strncmp("quit",buf,4) == 0)
    52         break;        
    53     }
    54     return ;
    55 }
    56 
    57 int main()
    58 {
    59     //1. 初始化socket
    60     int sfd = init_socket();
    61     //2. 通信
    62     deal_communication(sfd);
    63     return 0;
    64 }
  • 相关阅读:
    oracle对象之序列
    PLSql工具介绍
    oracle对象之同义词
    oracle对象之视图
    缓存问题汇总
    消息队列问题汇总
    算法-排序算法-1
    redis-主从数据一致
    数据结构与算法-完全二叉树/满二叉树
    写缓冲器与无效化队列
  • 原文地址:https://www.cnblogs.com/Bro-Young/p/5766167.html
Copyright © 2020-2023  润新知