I/O多路转接之select——基于TCP协议

  1. 关于select的基础知识

    a. select是系统提供的多路复用输入输出模型。它是用来监视多个文件句柄的状态变化。

    b. 程序会停在select等,直到被监视的文件句柄至少有一个发生了状态改变。

    c. 文件句柄是整数

  2. 函数

a. 参数

nfds:需要监视的最大文件描述符值加1;

struct timeval结构用于描述一段时间长度,若超出这个时间,需要监视的描述符没有发生,则返回0。

3.代码实现

 21     //
 22     int sock=socket(AF_INET,SOCK_STREAM,0);
 23     if(sock<0)
 24     {
 25         perror("socket");
 26         exit(1);
 27     }
 28     //
 28          //
 29     struct sockaddr_in local;
 30     local.sin_family=AF_INET;
 31     local.sin_port=htons(port);
 32     local.sin_addr.s_addr=inet_addr(ip);
 33     //
 34     if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)
 35     {
 36         perror("bind");
 37         exit(2);
 38     }
 39     //
 40     if(listen(sock,_BACKLOG_)<0)
 41     {
 42         perror("listen");
 43         exit(3);
 44     }
 45     return sock;
 46 }
 47 int main(int argc,char*argv[])
 48 {
 49     if(argc!=3)
 50     {
 51         usage(argv[0]);
 52         exit(1);
 53     }
 54 
 55     char* ip=argv[1];
 56     int port=atoi(argv[2]);
 57 
 58     int listen_sock=startup(ip,port);
 59 
 60     int done=0;
 61     int new_sock=-1;
 62     struct sockaddr_in client;
 63     socklen_t len=sizeof(client);
 64 
 65     int max_fd;
 66     fd_set _reads;
 67     fd_set _writes;
 68 
 69     int i=0;
 70     int fds_num=sizeof(fds)/sizeof(fds[0]);
 71     for(;i<fds_num;++i)
 72     {
 73         fds[i]=-1;
 74     }
 75     fds[0]=listen_sock;
 76     max_fd=fds[0];
 77 
 78     while(!done)
 79     {
 80         FD_ZERO(&_reads);
 81         FD_ZERO(&_writes);
 82         FD_SET(listen_sock,&_reads);
 83         struct timeval _timeout={5,0};
 84         for(i=1;i<fds_num;++i)
 85         {
 86             if(fds[i]>0)
 87             {
 88                 FD_SET(fds[i],&_reads);
 89                 if(fds[i]>max_fd)
 90                 {
 91                     max_fd=fds[i];
 92                 }
 93             }
 94         }
 95         switch(select(max_fd+1,&_reads,&_writes,NULL,NULL))
 96         {
 97             case 0:
 98                 //timeout
 99                 printf("timeout\n");
100                 break;
101             case -1:
102                 perror("select");
103                 break;
104             default:
105                 {
106                     i=0;
107                     for(;i<fds_num;++i)
108                     {
109                         if(fds[i]==listen_sock&&FD_ISSET(fds[i],&_reads))
110                         {
111                             //listen socket is ready!
112                             new_sock=accept(listen_sock,(struct sockaddr*)&client,&len);
113                             if(new_sock<0)
114                             {
115                                 perror("accept");
116                                 continue;
117                             }
118                             printf("get a new connect...%d\n",new_sock);
119                             for(i=0;i<fds_num;++i)
120                             {
121                                 if(fds[i]==-1)
122                                 {
123                                     fds[i]=new_sock;
124                                     break;
125                                 }
126                             }
127                             if(i==fds_num)
128                             {
129                                 close(new_sock);
130                             }
131                         }
132                         //listen socket
133                         else if(fds[i]>0 && FD_ISSET(fds[i],&_reads))
134                         {
135                             char buf[1024];
136                             ssize_t _s=read(fds[i],buf,sizeof(buf)-1);
137                             if(_s>0)
138                             {
139                                 //read sucess
140                                 buf[_s]=‘\0‘;
141                                 printf("client:%s\n",buf);
142                             }
143                             else if(_s==0)
144                             {
145                                 //client shutdown
146                                 printf("client shutdown...\n");
147                                 close(fds[i]);
148                                 fds[i]=-1;
149                             }
150                             else
151                             {
152                                 perror("read");
153                             }
154                         }
155                         //normal socket
156                         else
157                         {}
158                     }
159                 }
160                 break;
161         }
162     }
163     return 0;
164 }
时间: 2024-12-16 18:50:59

I/O多路转接之select——基于TCP协议的相关文章

【Nginx】I/O多路转接之select、poll、epoll

从socket中读取数据可以使用如下的代码: while( (n = read(socketfd, buf, BUFSIZE) ) >0) if( write(STDOUT_FILENO, buf, n) = n) { printf(“write error”); exit(1); } 当代码中的socketfd描述符所对应的文件表项是处于阻塞时,它会一直阻塞,直到有数据从网络的另一端发送过来.如果它是一个服务器程序,它要读写大量的socket,那么在某一个socket上的阻塞很明显会影响与其它

Android基础入门教程——7.6.3 基于TCP协议的Socket通信(2)

Android基础入门教程--7.6.3 基于TCP协议的Socket通信(2) 标签(空格分隔): Android基础入门教程 本节引言: 上节中我们给大家接触了Socket的一些基本概念以及使用方法,然后写了一个小猪简易聊天室的 Demo,相信大家对Socket有了初步的掌握,本节我们来学习下使用Socket来实现大文件的断点续传! 这里讲解的是别人写好的一个Socket上传大文件的例子,不要求我们自己可以写出来,需要的时候会用 就好! 1.运行效果图: 1.先把我们编写好的Socket服务

网络编程——基于TCP协议的Socket编程,基于UDP协议的Socket编程

Socket编程 目前较为流行的网络编程模型是客户机/服务器通信模式 客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求.如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服务器进程B1同时为客户进程A1.A2和B2提供服务. Socket概述 ①   所谓Socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过“套接字”向网络发出请求或者应答网络请求. ②   Socket是连接运行在网络上的两个程序间的双向通信的端点. ③  

基于TCP协议的网络通信

**重点内容**1.使用InetAddress(IP地址类) 这个类有点儿奇葩,没有提供构造方法.而是有两个静态方法来实例化. ·getByName(String host) 通过主机名获取对应的InetAddress对象 ·getByAddress(byte[] addr) 通过IP地址获取对应的InetAddress对象 getCononicalHostName() 获取IP地址的全限定域名 getHostAddress() 返回IP地址字符串 getHostName() 获取IP地址的主机

用c++开发基于tcp协议的文件上传功能

用c++开发基于tcp协议的文件上传功能 2005我正在一家游戏公司做程序员,当时一直在看<Windows网络编程> 这本书,把里面提到的每种IO模型都试了一次,强烈推荐学习网络编程的同学阅读,比 APUE 讲的更深入 这是某个银行广告项目(p2p传输视频)的一部分 IO模型采用的阻塞模式,文件一打开就直接上传 用vc 2003编译,生成win32 dll 麻雀虽小五脏俱全,CSimpleSocket,CReadStream dll 输出一虚类 extern "C" __d

浅析C#基于TCP协议的SCOKET通信

TCP协议是一个基本的网络协议,基本上所有的网络服务都是基于TCP协议的,如HTTP,FTP等等,所以要了解网络编程就必须了解基于TCP协议的编程.然而TCP协议是一个庞杂的体系,要彻底的弄清楚它的实现不是一天两天的功夫,所幸的是在.net framework环境下,我们不必要去追究TCP协议底层的实现,一样可以很方便的编写出基于TCP协议进行网络通讯的程序. C#基于TCP协议的网络通讯 要进行C#基于TCP协议的网络通讯,首先必须建立同远程主机的连接,连接地址通常包括两部分--主机名和端口,

基于TCP协议的服务器中转简易聊天

项目比较简单:主要使用了TCP传输协议.多线程和swing窗口,以及IO流读写. 功能:各窗口之间简单的收发信息,另外附加一个抖动的效果. 服务器代码: 1 package com.java; 2 3 import java.awt.Dimension; 4 import java.awt.Toolkit; 5 import java.awt.event.ActionEvent; 6 import java.awt.event.ActionListener; 7 import java.awt.

基于TCP协议的简单Socket通信笔记(JAVA)

好久没写博客了,前段时间忙于做项目,耽误了些时间,今天开始继续写起~ 今天来讲下关于Socket通信的简单应用,关于什么是Socket以及一些网络编程的基础,这里就不提了,只记录最简单易懂实用的东西. 1.首先先来看下基于TCP协议Socket服务端和客户端的通信模型: Socket通信步骤:(简单分为4步) 1.建立服务端ServerSocket和客户端Socket 2.打开连接到Socket的输出输入流 3.按照协议进行读写操作 4.关闭相对应的资源 2.相关联的API: 1.首先先来看下S

Android基础入门教程——7.6.2 基于TCP协议的Socket通信(1)

Android基础入门教程--7.6.2 基于TCP协议的Socket通信(1) 标签(空格分隔): Android基础入门教程 本节引言: 上一节的概念课枯燥无味是吧,不过总有点收获是吧,本节开始我们来研究基于TCP协议的Socket 通信,先来了解下Socket的概念,以及Socket通信的模型,实现Socket的步骤,以及作为Socket服务 端与客户端的两位各做要做什么事情!好的,我们由浅入深来扣这个Socket吧! 1.什么是Socket? 2.Socket通信模型: Socket通信