select -贾文龙
来源:互联网 发布:软件外包项目交接 编辑:程序博客网 时间:2024/05/04 03:59
select(09嵌入式-贾文龙-注释
/* server.c */
#include
#include
#include
#include
#include "wrap.c"
#define MAXLINE 80
#define SERV_PORT 8000
int main(int argc, char **argv)
{
int i, maxi, maxfd, listenfd, connfd, sockfd;
int nready, client[FD_SETSIZE];
ssize_t n;
fd_set rset, allset;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];//宏定义INET_ADDRSTRLEN用于保存网络二进制地址转换为点分十进制地址
socklen_t cliaddr_len;
struct sockaddr_in cliaddr, servaddr;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);//打开一个网络通讯端口
bzero(&servaddr, sizeof(servaddr));//初始化 servaddr 将整个结构体清零
servaddr.sin_family = AF_INET;//设置地址类型为AF_INET
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//网络地址为INADDR_ANY
servaddr.sin_port = htons(SERV_PORT);//端口号
int opt = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
//将参数listenfd和servaddr绑定在一起,使listenfd这个用于网络通讯的文件描述符监听servaddr所描述的地址和端口号
Listen(listenfd, 20);
maxfd = listenfd; /* 初始化maxfd作为select的第一个参数--最大的文件描述符加一*/
maxi = -1; /* index into client[] array */
for (i = 0; i < FD_SETSIZE; i++)
client[i] = -1; /*初始化client[]为 -1 : 指示可获得的输入项*/
FD_ZERO(&allset); //清空集合
FD_SET(listenfd, &allset); //将listenfd文件描述符加入集合之中
for ( ; ; )
{
rset = allset; /* structure assignment */
nready = select(maxfd+1, &rset, NULL, NULL, NULL);//确定rset中套接字的状态
if (nready < 0)
perr_exit("select error");
if (FD_ISSET(listenfd, &rset)) //判断 listenfd 是否在rset中
{ /* new client connection */
cliaddr_len = sizeof(cliaddr);
connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);
printf("received from %s at PORT %d\n",
inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
ntohs(cliaddr.sin_port));
for (i = 0; i < FD_SETSIZE; i++)
if (client[i] < 0)
{
client[i] = connfd; /* save descriptor */
break;
}
if (i == FD_SETSIZE)
{
fputs("too many clients\n", stderr);
exit(1);
}
FD_SET(connfd, &allset); /* add new descriptor to set */
if (connfd > maxfd)
maxfd = connfd; /* for select */
if (i > maxi)
maxi = i; /* max index in client[] array */
if (--nready == 0)
continue; /* no more readable descriptors */
}
for (i = 0; i <= maxi; i++)
{ /* check all clients for data */
if ( (sockfd = client[i]) < 0)
continue;
if (FD_ISSET(sockfd, &rset))
{
if ( (n = Read(sockfd, buf, MAXLINE)) == 0)
{
/* connection closed by client */
Close(sockfd);
FD_CLR(sockfd, &allset);
client[i] = -1;
} else
{
int j;
for (j = 0; j < n; j++)
buf[j] = toupper(buf[j]);
Write(sockfd, buf, n);
}
if (--nready == 0)
break; /* no more readable descriptors */
}
}
}
}
执行过程:
服务器先运行,定义变量并初始化一些变量,for循环,把allset的值赋值给rset,调用select()等待客户端连接,如果有客户端运行,select()返回,判断nready如果小于0就说明出错 退出,否则就判断lisentfd是否在rset里面,在就接受连接,用connfd 代替listenfd 与客户端通信。输出 客户端ip 和端口 ,然后保存 新建的描述符,在判断是否有太多的客户端 若太多 退出。 否则 把connfd 保存进allset 然后在把最大的 文件描述符赋值给maxfd.如果此时 --nready 等于0 那么 就再次循环把allset 的值赋值给rset 此时 select()已经有了一个套接字对象处于满足条件的状态。判断 lisentfd是否在rset里面 此时 rset被allset赋值 只有connfd 不再执行if后面的语句。
执行for循环把上一面新建的描述符赋值给sockfd 并判断这个描述符是否小于0 ,如果小于0说明 client[i]里面没有新的文件描述符,就再次回到第一个for循环处执行。否则就判断 sockfd 在不在rset中,如果在,在判断能不能从客户端读取数据,如果能就执行else下面的语句 并把处理过得数据传回客户端,如果不能 说明客户端一关闭连接,就把新建的文件描述符关闭,并从allset中删除,把client[i]赋值为-1。接着判断--nready是否等于0 如果等于0 就退出本次循环,否则在次循环,判断另一个客户端(client[i])是否有输入有输入就处理并返回客户端,没有就关闭另一个客户端描述符。循环结束时,在执行上一个循环 ,重新接受新的客户端请求。一直循环。
/* server.c */
#include
#include
#include
#include
#include "wrap.c"
#define MAXLINE 80
#define SERV_PORT 8000
int main(int argc, char **argv)
{
int i, maxi, maxfd, listenfd, connfd, sockfd;
int nready, client[FD_SETSIZE];
ssize_t n;
fd_set rset, allset;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];//宏定义INET_ADDRSTRLEN用于保存网络二进制地址转换为点分十进制地址
socklen_t cliaddr_len;
struct sockaddr_in cliaddr, servaddr;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);//打开一个网络通讯端口
bzero(&servaddr, sizeof(servaddr));//初始化 servaddr 将整个结构体清零
servaddr.sin_family = AF_INET;//设置地址类型为AF_INET
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//网络地址为INADDR_ANY
servaddr.sin_port = htons(SERV_PORT);//端口号
int opt = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
//将参数listenfd和servaddr绑定在一起,使listenfd这个用于网络通讯的文件描述符监听servaddr所描述的地址和端口号
Listen(listenfd, 20);
maxfd = listenfd; /* 初始化maxfd作为select的第一个参数--最大的文件描述符加一*/
maxi = -1; /* index into client[] array */
for (i = 0; i < FD_SETSIZE; i++)
client[i] = -1; /*初始化client[]为 -1 : 指示可获得的输入项*/
FD_ZERO(&allset); //清空集合
FD_SET(listenfd, &allset); //将listenfd文件描述符加入集合之中
for ( ; ; )
{
rset = allset; /* structure assignment */
nready = select(maxfd+1, &rset, NULL, NULL, NULL);//确定rset中套接字的状态
if (nready < 0)
perr_exit("select error");
if (FD_ISSET(listenfd, &rset)) //判断 listenfd 是否在rset中
{ /* new client connection */
cliaddr_len = sizeof(cliaddr);
connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);
printf("received from %s at PORT %d\n",
inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
ntohs(cliaddr.sin_port));
for (i = 0; i < FD_SETSIZE; i++)
if (client[i] < 0)
{
client[i] = connfd; /* save descriptor */
break;
}
if (i == FD_SETSIZE)
{
fputs("too many clients\n", stderr);
exit(1);
}
FD_SET(connfd, &allset); /* add new descriptor to set */
if (connfd > maxfd)
maxfd = connfd; /* for select */
if (i > maxi)
maxi = i; /* max index in client[] array */
if (--nready == 0)
continue; /* no more readable descriptors */
}
for (i = 0; i <= maxi; i++)
{ /* check all clients for data */
if ( (sockfd = client[i]) < 0)
continue;
if (FD_ISSET(sockfd, &rset))
{
if ( (n = Read(sockfd, buf, MAXLINE)) == 0)
{
/* connection closed by client */
Close(sockfd);
FD_CLR(sockfd, &allset);
client[i] = -1;
} else
{
int j;
for (j = 0; j < n; j++)
buf[j] = toupper(buf[j]);
Write(sockfd, buf, n);
}
if (--nready == 0)
break; /* no more readable descriptors */
}
}
}
}
执行过程:
服务器先运行,定义变量并初始化一些变量,for循环,把allset的值赋值给rset,调用select()等待客户端连接,如果有客户端运行,select()返回,判断nready如果小于0就说明出错 退出,否则就判断lisentfd是否在rset里面,在就接受连接,用connfd 代替listenfd 与客户端通信。输出 客户端ip 和端口 ,然后保存 新建的描述符,在判断是否有太多的客户端 若太多 退出。 否则 把connfd 保存进allset 然后在把最大的 文件描述符赋值给maxfd.如果此时 --nready 等于0 那么 就再次循环把allset 的值赋值给rset 此时 select()已经有了一个套接字对象处于满足条件的状态。判断 lisentfd是否在rset里面 此时 rset被allset赋值 只有connfd 不再执行if后面的语句。
执行for循环把上一面新建的描述符赋值给sockfd 并判断这个描述符是否小于0 ,如果小于0说明 client[i]里面没有新的文件描述符,就再次回到第一个for循环处执行。否则就判断 sockfd 在不在rset中,如果在,在判断能不能从客户端读取数据,如果能就执行else下面的语句 并把处理过得数据传回客户端,如果不能 说明客户端一关闭连接,就把新建的文件描述符关闭,并从allset中删除,把client[i]赋值为-1。接着判断--nready是否等于0 如果等于0 就退出本次循环,否则在次循环,判断另一个客户端(client[i])是否有输入有输入就处理并返回客户端,没有就关闭另一个客户端描述符。循环结束时,在执行上一个循环 ,重新接受新的客户端请求。一直循环。
0
上一篇:server-client 服务器 客户端 李春玲
下一篇:select分析 闫俊霖
相关热门文章
- SHTML是什么_SSI有什么用...
- shell中字符串操作
- 卡尔曼滤波的原理说明...
- 关于java中的“错误:找不到或...
- shell中的特殊字符
- linux dhcp peizhi roc
- 关于Unix文件的软链接
- 求教这个命令什么意思,我是新...
- sed -e "/grep/d" 是什么意思...
- 谁能够帮我解决LINUX 2.6 10...
给主人留下些什么吧!~~
评论热议
0 0
- select -贾文龙
- select()
- select
- select
- select
- select
- select
- select
- select
- select()
- select
- Select .....
- Select
- select
- select ''
- select
- select
- select
- server-client 服务器 客户端 李春玲
- 【BZOJ1066】[SCOI2007]蜥蜴【最大流】
- 宏杉科技针对传统RAID缺陷推CRAID 3.0
- 人脸识别系统的设计与思考(原创)
- 202. Happy Number
- select -贾文龙
- select分析 闫俊霖
- 客户端-服务器(client-server) 贾文龙
- 嵌入式系统移植基础三部曲 段彦青
- 运用RUP 4+1视图方法进行软件架构设计
- 职位 工作
- linux下网上银行+支付宝+淘宝购物
- html你真的学懂了嘛?
- 雨林木风诚聘Linux研发工程师
原创粉丝点击
热门IT博客
热门问题
老师的惩罚
人脸识别
我在镇武司摸鱼那些年
重生之率土为王
我在大康的咸鱼生活
盘龙之生命进化
天生仙种
凡人之先天五行
春回大明朝
姑娘不必设防,我是瞎子
蓑衣意思
蓑笠的拼音
蓑衣图片
一蓑烟雨任平生全文
蓑衣的意思
蓑笠翁
烟蓑雨笠
一蓑烟雨任平生什么暗含意思
蓑笠
蓑衣饭
水蓑衣
暴走英雄坛蓑衣在哪
蓑衣茄子的做法
簑衣
蓑衣刀法图解
蓑衣什么意思
蓑衣刀法
蓑衣是什么意思
蓑衣读音
蓑衣茄子
糖醋蓑衣黄瓜
蓑衣阅读答案
不脱蓑衣卧月明
蓑衣黄瓜的切法
蓑衣黄瓜怎么切
蓑衣蛋
蓑衣黄瓜的做法
凉拌蓑衣黄瓜
箬笠蓑衣
雨裂水蓑衣
蓑衣的图片
蓓丽
koumis 蓓丽
la prairie 蓓丽
laprairie什么牌子
莱珀妮
蓓蓓
蓓蓓8部
蓖
蓖怎么读
蓖麻