Socket编程之Select模型

echoserver_select.c

  1 #include <apue.h>
  2
  3 #define BACKLOG 10
  4 #define PORT 8080
  5 #define MAXCLIENT 20
  6 #define LEN_BUF 255
  7
  8 fd_set grset;
  9 int maxfd;
 10 struct client
 11 {
 12     char ip[16];
 13     unsigned short port;
 14     int connfd;
 15 };
 16
 17 struct client *gclients[MAXCLIENT];
 18 int curclient;
 19
 20 void readclient(int index);
 21 void acceptnewconnection(int sockfd);
 22
 23 int main(int argc,char **argv)
 24 {
 25     //1.socket
 26     int sockfd;
 27     if((sockfd = socket(PF_INET,SOCK_STREAM,0))<0)
 28         ERR("socket failed");
 29
 30     //2.reuseaddr
 31     int val = 1;
 32     if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(val))<0)
 33         ERR("set reuse addr failed");
 34
 35     //3.bind
 36     struct sockaddr_in ipv4;
 37     CLEAR(ipv4);
 38     ipv4.sin_family = AF_INET;
 39     ipv4.sin_port = htons(PORT);
 40     ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
 41
 42     if(bind(sockfd,(struct sockaddr*)&ipv4,sizeof(ipv4))<0)
 43         ERR("bind failed");
 44
 45     //4.listen
 46     listen(sockfd,BACKLOG);
 47
 48     fd_set rset;
 49     FD_ZERO(&grset);
 50     FD_SET(sockfd,&grset);
 51     maxfd = MAXOR(maxfd,sockfd);
 52
 53     while(1)
 54     {
 55         rset = grset;
 56         if(select(maxfd+1,&rset,NULL,NULL,NULL)<0)
 57             ERR("select failed");
 58         if(FD_ISSET(sockfd,&rset))
 59         {
 60             acceptnewconnection(sockfd);
 61         }
 62         int i;
 63         for(i=0;i<MAXCLIENT;i++)
 64         {
 65             if(gclients[i]==NULL)
 66                 continue;
 67             if(FD_ISSET(gclients[i]->connfd,&rset))
 68             {
 69                 readclient(i);
 70             }
 71         }
 72     }
 73
 74     return 0;
 75 }
 76
 77 void readclient(int index)
 78 {
 79     struct client *clp;
 80     clp = gclients[index];
 81     char buf[LEN_BUF];
 82     int n;
 83     if((n = read(clp->connfd,buf,sizeof(buf)))<0)
 84         ERR("write failed");
 85     else if(n==0)
 86     {
 87         printf("Connection is closed by peer!\n");
 88         close(clp->connfd);
 89         FD_CLR(clp->connfd,&grset);
 90         free(clp);
 91         gclients[index] = NULL;
 92         curclient--;
 93     }
 94     else
 95     {
 96         if(write(clp->connfd,buf,n)<0)
 97             ERR("write failed");
 98     }
 99 }
100
101 void acceptnewconnection(int sockfd)
102 {
103     if(curclient==MAXCLIENT)
104         return;
105     int connfd;
106     struct sockaddr_in peer;
107     socklen_t len;
108     if((connfd = accept(sockfd,(struct sockaddr*)&peer,&len))<0)
109         ERR("accept failed");
110
111     //send banner
112     unsigned short peerport = ntohs(peer.sin_port);
113     char ipstr[] = "ddd.ddd.ddd.ddd";
114     inet_ntop(AF_INET, &peer.sin_addr, ipstr, sizeof(ipstr));
115     char banner[255];
116     sprintf(banner, "[%s:%d] welcome to echoserver!", ipstr,peerport);
117     printf("Accept a new Connection: %s,%d\n",ipstr,peerport);
118     if(write(connfd, banner, strlen(banner)) < strlen(banner))
119         ERR("write failed");
120
121     //add connfd to grset
122     FD_SET(connfd,&grset);
123     maxfd = MAXOR(maxfd,connfd);
124
125     //add client to gclients
126     struct client *clp;
127     clp = malloc(sizeof(struct client));
128     if(clp==NULL)
129         exit(-1);
130     strcpy(clp->ip,ipstr);
131     clp->port = peerport;
132     clp->connfd = connfd;
133
134     int i;
135     for(i=0;i<MAXCLIENT;i++)
136     {
137         if(gclients[i]==NULL)
138         {
139             gclients[i] = clp;
140             break;
141         }
142     }
143     curclient++;
144 }

echoclient.c

 1 #include <apue.h>
 2
 3 void do_business(int sockfd);
 4
 5 int main(int argc,char **argv)
 6 {
 7     //1.判断命令行
 8     if(argc!=3)
 9     {
10         printf("Usage: %s <host> <port>\n",argv[0]);
11         exit(0);
12     }
13     char *ipstr = argv[1];
14     unsigned short port = strtol(argv[2],NULL,10);
15
16     //2.socket
17     int sockfd;
18     if((sockfd = socket(PF_INET,SOCK_STREAM,0))<0)
19         ERR("socket failed");
20
21     //3.connect
22     struct hostent *ent;
23     if((ent=gethostbyname(ipstr))==NULL)
24         ERR("gethostbyname failed");
25
26     struct sockaddr_in peer;
27     CLEAR(peer);
28     peer.sin_family = AF_INET;
29     peer.sin_port = htons(port);
30     //inet_pton(AF_INET,ipstr,&peer.sin_addr);
31     memcpy(&peer.sin_addr,ent->h_addr,sizeof(struct in_addr));
32     if(connect(sockfd,(struct sockaddr*)&peer,sizeof(peer))<0)
33         ERR("connect failed");
34
35     //4.交互
36     char banner[255];
37     int n;
38     if((n = read(sockfd,banner,sizeof(banner)))<0)
39         ERR("read failed");
40     else if(n==0)
41         goto end;
42     banner[n] = 0;
43     printf("%s\n",banner);
44
45     do_business(sockfd);
46
47     //5.关闭
48 end:
49     close(sockfd);
50
51     return 0;
52 }
53
54 void do_business(int sockfd)
55 {
56     int n;
57     char buf[255],msg[255];
58     while(1)
59     {
60         printf("shell# ");
61         fflush(stdout);
62         scanf("%s",buf);
63         if(write(sockfd,buf,strlen(buf))<0)
64             ERR("write failed");
65         if((n = read(sockfd,msg,sizeof(msg)))<0)
66             ERR("read failed");
67         else if(n==0)
68             break;
69         msg[n] = 0;
70         printf("%s\n",msg);
71     }
72 }

Socket编程之Select模型

时间: 2024-10-29 00:32:53

Socket编程之Select模型的相关文章

Python socket编程之IO模型介绍(多路复用*)

1.I/O基础知识 1.1 什么是文件描述符? 在网络中,一个socket对象就是1个文件描述符,在文件中,1个文件句柄(即file对象)就是1个文件描述符.其实可以理解为就是一个“指针”或“句柄”,指向1个socket或file对象,当file或socket发生改变时,这个对象对应的文件描述符,也会发生相应改变. 1.2 什么是I/O 1.先了解什么是I/O? I/O(input/output),即输入/输出.操作系统会对IO设备进行编址,IO设备用操作系统分配的地址来处理自己的输入输出信息.

socket编程之select()

Select在Socket编程中还是比较重要的,它能够监视我们需要监视的文件描述符的变化情况——读写或是异常. Select的函数格式(Unix系统下的伯克利socket编程,和windows下的略有区别,体现两个方面:一是select函数的第一个参数,在windows下可以忽略,但在linux下必须设为最大文件描述符加1:二是结构fd_set在两个系统里定义不一样): int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *

异步套接字编程之select模型

█ 选择(select)模型是Winsock中最常见的 I/O模型.核心便是利用 select 函数,实现对 I/O的管理!利用 select 函数来判断某Socket上是否有数据可读,或者能否向一个套接字写入数据,防止程序在Socket处于阻塞模式中时,在一次 I/O 调用(如send或recv.accept等)过程中,被迫进入“锁定”状态:同时防止在套接字处于非阻塞模式中时,产生WSAEWOULDBLOCK错误. █ select 的函数原型如下:int select(  __in    

socket编程之 select、poll、kqueue、epoll

原生API select int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); 函数参数 numfds:文件描述符的最大值+1(为了限制检测文件描述符的范围) readfds:包含所有因为状态变为可读而触发select函数返回文件描述符 writefds:包含所有因为状态变为可写而触发select函数返回文件描述符 exceptfds:包含所有因

socket编程之select(),poll(),epoll()

socket编程,通信 client端  socket() ----->connect() ------->recv() -----> close(); server端 socket() ----->bind()  ------> listen() ---->accept() ------>send() ------->close(); 1> socket(int family,int type,int protocol); family ->协

Python学习【第26篇】:并发编程之IO模型

python并发编程之IO模型, 了解新知识之前需要知道的一些知识 同步(synchronous):一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行 #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不会返回.按照这个定义,其实绝大多数函数都是同步调用.但是一般而言,我们在说同步.异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务. #举例: #1. multiprocessing.Pool下的apply #发起同步调用后,就在原地等着任务结束,

网络编程之IO模型——非阻塞IO

网络编程之IO模型--非阻塞IO 非阻塞IO(non-blocking IO) Linux下,可以通过设置socket使其变为non-blocking.当对一个non-blocking socket执行读操作时,流程是这个样子: 从图中可以看出,当用户进程发出read操作时,如果kernel中的数据还没有准备好,那么它并不会block用户进程,而是立刻返回一个error.从用户进程角度讲 ,它发起一个read操作后,并不需要等待,而是马上就得到了一个结果.用户进程判断结果是一个error时,它就

网络编程之IO模型——selectors模块

网络编程之IO模型--selectors模块 一.了解select,poll,epoll IO复用:为了解释这个名词,首先来理解下复用这个概念,复用也就是共用的意思,这样理解还是有些抽象, 为此,咱们来理解下复用在通信领域的使用,在通信领域中为了充分利用网络连接的物理介质. 往往在同一条网络链路上采用时分复用或频分复用的技术使其在同一链路上传输多路信号,到这里我们就基本上理解了复用的含义, 即公用某个"介质"来尽可能多的做同一类(性质)的事,那IO复用的"介质"是什

socket编程之二:两种链接类型upd和upd

前面一篇文章说到了一些计算机网络的基础知识,引入了socket,从这节开始,就进入正题了. 一 概率 TCP:Transimission Control Protocol传输控制协议. UPD:User Datagram Protocol用户数据包协议. 两者都属于上一篇文章说的OSI模型中的第四层--传输层的协议. 两者相比: TCP协议面向连接,UDP协议面向非连接:(链接) TCP协议传输速度慢,UDP协议传输速度快:(速度) TCP有丢包重传机制,UDP没有:(重传) TCP协议保证数据