Chinaunix首页 | 论坛 | 博客
  • 博客访问: 65473
  • 博文数量: 12
  • 博客积分: 230
  • 博客等级: 入伍新兵
  • 技术积分: 210
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-22 13:20
文章分类

全部博文(12)

文章存档

2012年(12)

我的朋友

分类: LINUX

2012-04-18 22:40:30

初始化过程:
关键:socket==>bind ==> listen;
定义listen_fd = socket(AF_INET, SOCK_STREAM, 0)
    配置socket套接字数据结构
    绑定地址:bind(listen_fd, (SA *)&serveraddr, sizeof(serveraddr));
    设置监听:listen(listen_fd, max_lsn);
创建一个循环监视:
while(1)循环实现:
1、设置读写文件描述符集合readfs;(初始化可设置一个标准输入和监听文件描述符)
其余设置为空;由于每次进行一次操作,循环回来初始化到原来状态;
2、调用select;
遍历当前所有存在的文件描述符;
if(i == listen_fd)//说明有新的连接请求,那么就建立连接
{  建立连接connect_fd == accept();然后将connect_fd 送进文件描集;}
else //说明其他操作针对的是已经存在的文件描述符、读、写、发送、接受、
{ 进行默契的操作}//end while(1);

///多路复用特点和应用:

除了可以采用多进程和多线程方法实现并发服务器之外,还可以采用I/O多路复用技术。通过该技术,系统内核缓冲I/O数据,当某个I/O准备好后,系统通知应用程序该I/O可读或可写,这样应用程序可以马上完成相应的I/O操作,而不需要等待系统完成相应I/O操作,从而应用程序不必因等待I/O操作而阻塞。

与多进程和多线程技术相比,I/O多路复用技术的最大优势是系统开销小,系统不必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。

对于I/O复用典型的应用如下:

(1)当客户处理多个描述字时(一般是交互式输入和网络套接口),必须使用I/O复用。

(2)当一个客户同时处理多个套接口时,而这种情况是可能的,但很少出现。

(3)如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般也要用到I/O复用。

(4)如果一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用。

(5)如果一个服务器要处理多个服务或多个协议,一般要使用I/O复用。

I/O复用调用select()或poll()函数,并在该函数上阻塞,等待数据报套接口可读;当select()返回可读条件时,调用recvfrom()将数据报拷贝到应用程序缓冲区中,


点击(此处)折叠或打开

  1. #include "server.h"

  2. int main()
  3. {
  4.     int listen_fd, connect_fd, max_fd;
  5.     struct sockaddr_in serveraddr, clientaddr;
  6.     char buf[MAXBUF];
  7.     int length;
  8.     fd_set rdfs, tempfs;
  9.     int num;


  10.     listen_fd = socket(AF_INET, SOCK_STREAM, 0);

  11.     memset(&serveraddr, 0, sizeof(serveraddr));
  12.     serveraddr.sin_family = AF_INET;
  13.     serveraddr.sin_port = htons(8000);
  14.     serveraddr.sin_addr.s_addr = inet_addr("192.168.0.104");

  15.     bind(listen_fd, (SA *)&serveraddr, sizeof(serveraddr));
  16.     listen(listen_fd, 10);
  17.     //connect_fd = bind();
  18.     
  19.     memset(buf, '\0', sizeof(buf));
  20.     FD_ZERO(&rdfs);
  21.     FD_SET(0, &rdfs);
  22.     FD_SET(listen_fd, &rdfs);
  23.     max_fd = listen_fd;
  24.     
  25.     int i;

  26.     while(1)
  27.     {
  28.         tempfs = rdfs;
  29.         printf("selecting...\n");

  30.         if((num = select(max_fd + 1, &tempfs, NULL, NULL, NULL))== -1)
  31.         {
  32.             perror("select failed!\n");
  33.             exit(-1);
  34.         }
  35.         else if(num > 0)
  36.         {
  37.             printf("the current fd stream number is : %d\n" , num);
  38.         }

  39.         printf("select success...\n");
  40.     //    sleep(1);
  41.         
  42.         for(i=0; i< max_fd + 1; i++)
  43.         {
  44.             if(FD_ISSET(i, &tempfs))
  45.             {
  46.                 if(i == STDIN_FILENO)
  47.                 {
  48.                     fgets(buf, sizeof(buf), stdin);
  49.                     printf("input :%s",buf);
  50.                 }

  51.                 if(i == listen_fd)
  52.                 {
  53.                     length = sizeof(clientaddr);
  54.                     printf("connecting...");
  55.                     connect_fd = accept(listen_fd, (SA *)&clientaddr, &length);
  56.                     printf("connected!\n");
  57.                     FD_SET(connect_fd, &rdfs);

  58.                     if(max_fd < connect_fd)
  59.                     {
  60.                         max_fd = connect_fd;
  61.                     }

  62.                     printf("IP: %s port: %d\n", inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
  63.                 }
  64.                 else
  65.                 {
  66.                     memset(buf, 0, sizeof(buf));
  67.                     read(i, buf, sizeof(buf));
  68.                     printf("Get Message:%s\n", buf);
  69.                     close(i);
  70.                     FD_CLR(i, &rdfs);

  71.                     if(max_fd == i)
  72.                     {
  73.                         max_fd --;
  74.                     }
  75.                 }

  76.             }
  77.         }
  78.     }

  79.     return 0;
  80. }

阅读(5760) | 评论(0) | 转发(3) |
给主人留下些什么吧!~~