初始化过程:
关键: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()将数据报拷贝到应用程序缓冲区中,
- #include "server.h"
- int main()
- {
- int listen_fd, connect_fd, max_fd;
- struct sockaddr_in serveraddr, clientaddr;
- char buf[MAXBUF];
- int length;
- fd_set rdfs, tempfs;
- int num;
- listen_fd = socket(AF_INET, SOCK_STREAM, 0);
- memset(&serveraddr, 0, sizeof(serveraddr));
- serveraddr.sin_family = AF_INET;
- serveraddr.sin_port = htons(8000);
- serveraddr.sin_addr.s_addr = inet_addr("192.168.0.104");
- bind(listen_fd, (SA *)&serveraddr, sizeof(serveraddr));
- listen(listen_fd, 10);
- //connect_fd = bind();
-
- memset(buf, '\0', sizeof(buf));
- FD_ZERO(&rdfs);
- FD_SET(0, &rdfs);
- FD_SET(listen_fd, &rdfs);
- max_fd = listen_fd;
-
- int i;
- while(1)
- {
- tempfs = rdfs;
- printf("selecting...\n");
- if((num = select(max_fd + 1, &tempfs, NULL, NULL, NULL))== -1)
- {
- perror("select failed!\n");
- exit(-1);
- }
- else if(num > 0)
- {
- printf("the current fd stream number is : %d\n" , num);
- }
- printf("select success...\n");
- // sleep(1);
-
- for(i=0; i< max_fd + 1; i++)
- {
- if(FD_ISSET(i, &tempfs))
- {
- if(i == STDIN_FILENO)
- {
- fgets(buf, sizeof(buf), stdin);
- printf("input :%s",buf);
- }
- if(i == listen_fd)
- {
- length = sizeof(clientaddr);
- printf("connecting...");
- connect_fd = accept(listen_fd, (SA *)&clientaddr, &length);
- printf("connected!\n");
- FD_SET(connect_fd, &rdfs);
- if(max_fd < connect_fd)
- {
- max_fd = connect_fd;
- }
- printf("IP: %s port: %d\n", inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
- }
- else
- {
- memset(buf, 0, sizeof(buf));
- read(i, buf, sizeof(buf));
- printf("Get Message:%s\n", buf);
- close(i);
- FD_CLR(i, &rdfs);
- if(max_fd == i)
- {
- max_fd --;
- }
- }
- }
- }
- }
- return 0;
- }
阅读(5764) | 评论(0) | 转发(3) |