蓝天模具的模具能压住i7么,准备入手了

客户端与服务端的交互_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
客户端与服务端的交互
上传于|0|0|暂无简介
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩13页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢select在客户端和服务器端绑定数据
selpage为select的id,select
&有加属性runat=server
selPage.i nner text
&+= "《option value=1》1《/option》“;
这种方式会报错:“HtmlSelect”不支持 InnerText
解决方式是:&
selPage.Items.Add(new
ListItem(text,value));
&agent.DataSource =取数据的方法
agent.DataTextField = "要显示的列名";
agent.DataValueField = "要显示的Value列名";
agent.DataBind();
agent.Items.Insert(0, new ListItem("全部", "-1"));//绑定后添加一个全部列
另外,select 就算加了runat=server属性,也不能在后台写触发事件,必须用DropDownList
清空:&ddlPage.Items.Clear();
& $("#selGame3")[0].options.add(new
Option("21", "福A撒打算"));
清空:& $("#selGame3")[0].options.length =
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。1658人阅读
UNP(API)(124)
& & &首先看原先《》的代码,服务器代码serv.c:#include&stdio.h&
#include&sys/types.h&
#include&sys/socket.h&
#include&unistd.h&
#include&stdlib.h&
#include&errno.h&
#include&arpa/inet.h&
#include&netinet/in.h&
#include&string.h&
#include&signal.h&
#define ERR_EXIT(m) \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
void do_service(int);
int main(void)
signal(SIGCHLD, SIG_IGN);
//被动套接字(文件描述符),即只可以accept, 监听套接字
if ((listenfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) & 0)
listenfd = socket(AF_INET, SOCK_STREAM, 0)
ERR_EXIT(&socket error&);
struct sockaddr_
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(5188);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
/* servaddr.sin_addr.s_addr = inet_addr(&127.0.0.1&); */
/* inet_aton(&127.0.0.1&, &servaddr.sin_addr); */
int on = 1;
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) & 0)
ERR_EXIT(&setsockopt error&);
if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) & 0)
ERR_EXIT(&bind error&);
if (listen(listenfd, SOMAXCONN) & 0) //listen应在socket和bind之后,而在accept之前
ERR_EXIT(&listen error&);
struct sockaddr_ //传出参数
socklen_t peerlen = sizeof(peeraddr); //传入传出参数,必须有初始值
// 已连接套接字(变为主动套接字,即可以主动connect)
if ((conn = accept(listenfd, (struct sockaddr *)&peeraddr, &peerlen)) & 0) //3次握手完成的序列
if( errno == EINTR )
///////////////////////////////////////////////////////////////////必须处理被中断的系统调用
ERR_EXIT(&accept error&);
printf(&recv connect ip=%s port=%d\n&, inet_ntoa(peeraddr.sin_addr),
ntohs(peeraddr.sin_port));
pid = fork();
if (pid == -1)
ERR_EXIT(&fork error&);
if (pid == 0)
close(listenfd);
do_service(conn);
exit(EXIT_SUCCESS);
close(conn); //父进程
void do_service(int conn)
char recvbuf[1024];
memset(recvbuf, 0, sizeof(recvbuf));
int ret = read(conn, recvbuf, sizeof(recvbuf));
if (ret == 0)
//客户端关闭了
printf(&client close\n&);
else if (ret == -1)
ERR_EXIT(&read error&);
fputs(recvbuf, stdout);
write(conn, recvbuf, ret);
}客户端代码cli.c:#include&stdio.h&
#include&sys/types.h&
#include&sys/socket.h&
#include&unistd.h&
#include&stdlib.h&
#include&errno.h&
#include&arpa/inet.h&
#include&netinet/in.h&
#include&string.h&
#define ERR_EXIT(m) \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
int main(void)
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) & 0)
listenfd = socket(AF_INET, SOCK_STREAM, 0)
ERR_EXIT(&socket error&);
struct sockaddr_
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(5188);
servaddr.sin_addr.s_addr = inet_addr(&127.0.0.1&);
/* inet_aton(&127.0.0.1&, &servaddr.sin_addr); */
if (connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) & 0)
ERR_EXIT(&connect error&);
struct sockaddr_
char cli_ip[20];
socklen_t local_len = sizeof(localaddr);
memset(&localaddr, 0, sizeof(localaddr));
if( getsockname(sock,(struct sockaddr *)&localaddr,&local_len) != 0 )
ERR_EXIT(&getsockname error&);
inet_ntop(AF_INET, &localaddr.sin_addr, cli_ip, sizeof(cli_ip));
printf(&host %s:%d\n&, cli_ip, ntohs(localaddr.sin_port));
char sendbuf[1024] = {0};
char recvbuf[1024] = {0};
while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)
write(sock, sendbuf, strlen(sendbuf));
read(sock, recvbuf, sizeof(recvbuf));
fputs(recvbuf, stdout);
memset(sendbuf, 0, sizeof(sendbuf));
memset(recvbuf, 0, sizeof(recvbuf));
close(sock);
}&先运行服务器端,再运行客户端:huangcheng@ubuntu:~$ ./serv
huangcheng@ubuntu:~$ ./cli先查看一下网络状态:huangcheng@ubuntu:~$ netstat -anp | grep 5188
(并非所有进程都能被检测到,所有非本用户的进程信息将不会显示,如果想看到所有信息,则必须切换到 root 用户)
0 0.0.0.0:5188
0 127.0.0.1:49484
127.0.0.1:5188
ESTABLISHED 2751/cli
0 127.0.0.1:5188
127.0.0.1:49484
ESTABLISHED 2752/serv
可以看出建立了连接,服务器端有两个进程,一个父进程处于监听状态,另一子进程正在对客户端进行服务。服务器端的子进程的pid为2752,并kill掉它:huangcheng@ubuntu:~$ kill -9 2752再查看一下网络状态:huangcheng@ubuntu:~$ netstat -anp | grep 5188
(并非所有进程都能被检测到,所有非本用户的进程信息将不会显示,如果想看到所有信息,则必须切换到 root 用户)
0 0.0.0.0:5188
0 127.0.0.1:49484
127.0.0.1:5188
CLOSE_WAIT
0 127.0.0.1:5188
127.0.0.1:49484
& & &来分析一下,我们将server子进程 &kill掉,则其终止时,socket描述符会自动关闭并发FIN段给client,client收到FIN后处于CLOSE_WAIT状态,但是client并没有终止,也没有关闭socket描述符,因此不会发FIN给 server子进程,因此server 子进程的TCP连接处于FIN_WAIT2状态。为什么会出现这种情况呢,来看client的部分程序:
char sendbuf[1024] = {0};
char recvbuf[1024] = {0};
while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)
write(sock, sendbuf, strlen(sendbuf));
read(sock, recvbuf, sizeof(recvbuf));
fputs(recvbuf, stdout);
memset(sendbuf, 0, sizeof(sendbuf));
memset(recvbuf, 0, sizeof(recvbuf));
}& & &客户端程序阻塞在了fgets 那里,即从标准输入读取数据,所以不能执行到下面的read,也即不能返回0,不会退出循环,不会调用close关闭sock,所以出现上述的情况,即状态停滞,不能向前推进。& & &出现上述问题的根本原因在于客户端程序不能并发处理从标准输入读取数据和从套接字读取数据两个事件,我们可以使用前面讲过的select函数来完善客户端程序。int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);参数1:读写异常集合中的文件描述符的最大值加1;参数2:读集合,关心可读事件;套接口缓冲区有数据可读连接的读一半关闭,即接收到FIN段,读操作将返回0如果是监听套接口,已完成连接队列不为空时。套接口上发生了一个错误待处理,错误可以通过getsockopt指定SO_ERROR选项来获取。参数3:写集合,关心可写事件;套接口发送缓冲区有空间容纳数据。连接的写一半关闭。即收到RST段之后,再次调用write操作。套接口上发生了一个错误待处理,错误可以通过getsockopt指定SO_ERROR选项来获取。参数4:异常集合,关心异常事件;套接口存在带外数据(TCP头部 URG标志,16位紧急指针字段)参数5:超时时间结构体对于参数2,3,4来说,如果不关心对应事件则设置为NULL即可。注意5个参数都是输入输出参数,即select返回时可能对其进行了修改,比如集合被修改以便标记哪些套接口发生了事件,时间结构体的传出参数是剩余的时间,如果设置为NULL表示永不超时。用select管理多个I/O,select阻塞等待,一旦其中的一个或多个I/O检测到我们所感兴趣的事件,select函数返回,返回值为检测到的事件个数,并且返回哪些I/O发送了事件,遍历这些事件,进而处理事件。注意当select阻塞返回后,此时调用read/write 是不会阻塞的,因为正是有可读可写事件发生才导致select 返回,也可以认为是select 提前阻塞了。下面是4个可以对集合进行操作的宏:void FD_CLR(int fd, fd_set *set); // 清除出集合
FD_ISSET(int fd, fd_set *set); // 判断是否在集合中
void FD_SET(int fd, fd_set *set); // 添加进集合中
void FD_ZERO(fd_set *set); // 将集合清零下面是通过select函数改进的客户端的代码cli.c:#include&stdio.h&
#include&sys/types.h&
#include&sys/socket.h&
#include&unistd.h&
#include&stdlib.h&
#include&errno.h&
#include&arpa/inet.h&
#include&netinet/in.h&
#include&string.h&
#define ERR_EXIT(m) \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
int main(void)
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) & 0)
listenfd = socket(AF_INET, SOCK_STREAM, 0)
ERR_EXIT(&socket error&);
struct sockaddr_
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(5188);
servaddr.sin_addr.s_addr = inet_addr(&127.0.0.1&);
/* inet_aton(&127.0.0.1&, &servaddr.sin_addr); */
if (connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) & 0)
ERR_EXIT(&connect error&);
struct sockaddr_
char cli_ip[20];
socklen_t local_len = sizeof(localaddr);
memset(&localaddr, 0, sizeof(localaddr));
if( getsockname(sock,(struct sockaddr *)&localaddr,&local_len) != 0 )
ERR_EXIT(&getsockname error&);
inet_ntop(AF_INET, &localaddr.sin_addr, cli_ip, sizeof(cli_ip));
printf(&host %s:%d\n&, cli_ip, ntohs(localaddr.sin_port));
FD_ZERO(&rset);
int fd_stdin = fileno(stdin); //
if (fd_stdin & sock)
maxfd = fd_
char sendbuf[1024] = {0};
char recvbuf[1024] = {0};
FD_SET(fd_stdin, &rset);
FD_SET(sock, &rset);
nready = select(maxfd + 1, &rset, NULL, NULL, NULL); //select返回表示检测到可读事件
if (nready == -1)
ERR_EXIT(&select error&);
if (nready == 0)
if (FD_ISSET(sock, &rset))
int ret = read(sock, recvbuf, sizeof(recvbuf));
if (ret == -1)
ERR_EXIT(&read error&);
else if (ret
//服务器关闭
printf(&server close\n&);
fputs(recvbuf, stdout);
memset(recvbuf, 0, sizeof(recvbuf));
if (FD_ISSET(fd_stdin, &rset))
if (fgets(sendbuf, sizeof(sendbuf), stdin) == NULL)
write(sock, sendbuf, strlen(sendbuf));
memset(sendbuf, 0, sizeof(sendbuf));
close(sock);
}& & &即将两个事件都添加进可读事件集合,在while循环中,如果select返回说明有事件发生,依次判断是哪些事件发生,如果是标准输入有数据可读,则读取后再次回到循环开头select阻塞等待事件发生,如果是套接口有数据可读,且返回为0则说明对方已经关闭连接,退出循环并调用close关闭sock。重复前面的操作:(1)先运行服务器,再运行客户端huangcheng@ubuntu:~$ ./serv
huangcheng@ubuntu:~$ ./cli(2)查看网络状态:huangcheng@ubuntu:~$ netstat -anp | grep 5188
(并非所有进程都能被检测到,所有非本用户的进程信息将不会显示,如果想看到所有信息,则必须切换到 root 用户)
0 0.0.0.0:5188
0 127.0.0.1:49485
127.0.0.1:5188
ESTABLISHED 2963/cli
0 127.0.0.1:5188
127.0.0.1:49485
ESTABLISHED 2964/serv
(3)kill掉服务器的子进程,再查看网络状态:huangcheng@ubuntu:~$ kill -9 2964
huangcheng@ubuntu:~$ netstat -anp | grep 5188
(并非所有进程都能被检测到,所有非本用户的进程信息将不会显示,如果想看到所有信息,则必须切换到 root 用户)
0 0.0.0.0:5188
0 127.0.0.1:5188
127.0.0.1:49485
& & &即 client 关闭socket描述符,server 子进程的TCP连接收到client发的FIN段后处于TIME_WAIT状态,此时会再发生一个ACK段给client,client接收到之后就处于CLOSED状态,这个状态存在时间很短,所以看不到客户端的输出条目,TCP协议规定,主动关闭连接的一方要处于TIME_WAIT状态,等待两个MSL(maximumsegment lifetime)的时间后才能回到CLOSED状态,需要有MSL 时间的主要原因是在这段时间内如果最后一个ack段没有发送给对方,则可以重新发送。& & &过一小会再次查看网络状态:huangcheng@ubuntu:~$ netstat -anp | grep 5188
(并非所有进程都能被检测到,所有非本用户的进程信息将不会显示,如果想看到所有信息,则必须切换到 root 用户)
0 0.0.0.0:5188
& & &可以发现只剩下服务器端父进程的监听状态了,由TIME_WAIT状态转入CLOSED状态,也很快会消失。-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------& & &前面我们实现的能够并发服务的服务器端程序是使用fork出多个子进程来实现的,现在学习了select函数,可以用它来改进服务器端程序,实现单进程并发服务。先看如下程序,再来解释:#include&stdio.h&
#include&sys/types.h&
#include&sys/socket.h&
#include&unistd.h&
#include&stdlib.h&
#include&errno.h&
#include&arpa/inet.h&
#include&netinet/in.h&
#include&string.h&
#include&signal.h&
#include&sys/wait.h&
#define ERR_EXIT(m) \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
int main(void)
signal(SIGPIPE, SIG_IGN);
//被动套接字(文件描述符),即只可以accept, 监听套接字
if ((listenfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) & 0)
listenfd = socket(AF_INET, SOCK_STREAM, 0)
ERR_EXIT(&socket error&);
struct sockaddr_
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(5188);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
/* servaddr.sin_addr.s_addr = inet_addr(&127.0.0.1&); */
/* inet_aton(&127.0.0.1&, &servaddr.sin_addr); */
int on = 1;
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) & 0)
ERR_EXIT(&setsockopt error&);
if (bind(listenfd, (struct sockaddr*)&servaddr,sizeof(servaddr)) & 0)
ERR_EXIT(&bind error&);
if (listen(listenfd, SOMAXCONN) & 0) //listen应在socket和bind之后,而在accept之前
ERR_EXIT(&listen error&);
struct sockaddr_ //传出参数
socklen_t peerlen = sizeof(peeraddr); //传入传出参数,必须有初始值
// 已连接套接字(变为主动套接字,即可以主动connect)
int client[FD_SETSIZE];
int maxi = 0; // client数组中最大不空闲位置的下标
for (i = 0; i & FD_SETSIZE; i++)
client[i] = -1;
int maxfd =
FD_ZERO(&rset);
FD_ZERO(&allset);
FD_SET(listenfd, &allset);
while (1) {
nready = select(maxfd + 1, &rset, NULL, NULL, NULL);
if (nready == -1) {
if (errno == EINTR)
ERR_EXIT(&select error&);
if (nready == 0)
if (FD_ISSET(listenfd, &rset)) {
conn = accept(listenfd, (struct sockaddr*)&peeraddr, &peerlen);
//accept不再阻塞
if (conn == -1)
ERR_EXIT(&accept error&);
for (i = 0; i & FD_SETSIZE; i++) {
if (client[i] & 0) {
client[i] =
if (i & maxi)
if (i == FD_SETSIZE) {
fprintf(stderr, &too many clients\n&);
exit(EXIT_FAILURE);
printf(&recv connect ip=%s port=%d\n&, inet_ntoa(peeraddr.sin_addr),
ntohs(peeraddr.sin_port));
FD_SET(conn, &allset);
if (conn & maxfd)
if (--nready &= 0)
for (i = 0; i &= i++) {
conn = client[i];
if (conn == -1)
if (FD_ISSET(conn, &rset)) {
char recvbuf[1024] = {0};
int ret = read(conn, recvbuf, 1024);
if (ret == -1)
ERR_EXIT(&readline error&);
else if (ret
== 0) { //客户端关闭
printf(&client close \n&);
FD_CLR(conn, &allset);
client[i] = -1;
close(conn);
fputs(recvbuf, stdout);
write(conn, recvbuf, strlen(recvbuf));
if (--nready &= 0)
/* select所能承受的最大并发数受
* 1.一个进程所能打开的最大文件描述符数,可以通过ulimit -n来调整
但一个系统所能打开的最大数也是有限的,跟内存有关,可以通过cat /proc/sys/fs/file-max 查看
* 2.FD_SETSIZE(fd_set)的限制,这个需要重新编译内核
*/& & &程序第一次进入while 循环,只把监听套接字加入关心的事件,select返回说明监听套接字有可读事件,即已完成连接队列不为空,这时调用accept不会阻塞,返回一个已连接套接字,将这个套接字加入allset,因为第一次运行则nready = 1,直接continue跳回到while 循环开头,再次调用select,这次会关心监听套接字和一个已连接套接字的可读事件,如果继续有客户端连接上来则继续将其加入allset,这次nready = 2,继续执行下面的for 循环,然后对客户端进行服务。服务完毕再次回到while 开头调用select 阻塞时,就关心一个监听套接字和2个已连接套接字的可读事件了,一直循环下去。& & &程序大概逻辑就这样,一些细节就大家自己想想了,比如client数组是用来保存已连接套接字的,为了避免每次都得遍历到FD_SETSIZE-1,保存一个最大不空闲下标maxi,每次遍历到maxi就可以了。每次得到一个conn,要判断一下conn与maxfd的大小。当得知某个客户端关闭,则需要将conn在allset中清除掉。之所以要有allset 和 rset 两个变量是因为rset是传入传出参数,在select返回时rset可能被改变,故需要每次在回到while 循环开头时需要将allset 重新赋予rset 。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:881358次
积分:12389
积分:12389
排名:第1019名
原创:303篇
转载:350篇
评论:42条
(3)(10)(3)(4)(2)(2)(5)(1)(1)(41)(1)(4)(3)(13)(14)(10)(5)(6)(4)(7)(1)(43)(173)(14)(125)(78)(2)(16)(64)Unix/Linux(72)
Unix环境高级编程(16)
&* 1. 程序使用了一个数组fd,通信开始后把需要通信的多个socket描述符都放入此数组
&* 2. 首先生成一个叫sock_fd的socket描述符,用于监听端口。
&* 3. 将sock_fd和数组fd中不为0的描述符放入select将检查的集合fdsr。
// select_server.c
#include &stdio.h&
#include &stdlib.h&
#include &unistd.h&
#include &errno.h&
#include &string.h&
#include &sys/types.h&
#include &sys/socket.h&
#include &sys/time.h&
#include &netinet/in.h&
#include &arpa/inet.h&
#define MYPORT 9999 //连接时使用的端口
#define MAXCLINE 5 //连接队列中的个数
#define BUF_SIZE 200
int fd[MAXCLINE]; //连接的fd
int conn_ //当前的连接数
void showclient()
& & printf(&client amount:%d\n&,conn_amount);
& & for(i=0;i&MAXCLINE;i++)
& & & & printf(&[%d]:%d &,i,fd[i]);
& & printf(&\n\n&);
int main(void)
& & int sock_fd,new_ //监听套接字 连接套接字
& & struct sockaddr_in server_ // 服务器的地址信息
& & struct sockaddr_in client_ //客户端的地址信息
& & socklen_t sin_
& & int yes = 1;
& & char buf[BUF_SIZE];
& & //建立sock_fd套接字
& & if((sock_fd = socket(AF_INET,SOCK_STREAM,0))==-1)
& & & & perror(&setsockopt&);
& & & & exit(1);
& & //设置套接口的选项 SO_REUSEADDR 允许在同一个端口启动服务器的多个实例
& & // setsockopt的第二个参数SOL SOCKET 指定系统中,解释选项的级别 普通套接字
& & if(setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))==-1)
& & & & perror(&setsockopt error \n&);
& & & & exit(1);
& & server_addr.sin_family = AF_INET; //主机字节序
& & server_addr.sin_port = htons(MYPORT);
& & server_addr.sin_addr.s_addr = INADDR_ANY;//通配IP
& & memset(server_addr.sin_zero,'\0',sizeof(server_addr.sin_zero));
& & if(bind(sock_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)) == -1)
& & & & perror(&bind error!\n&);
& & & & exit(1);
& & if(listen(sock_fd,MAXCLINE)==-1)
& & & & perror(&listen error!\n&);
& & & & exit(1);
& & printf(&listen port %d\n&,MYPORT);
& & fd_ //文件描述符集的定义
& & conn_amount =0;
& & sin_size = sizeof(client_addr);
& & maxsock = sock_
& & while(1)
& & //初始化文件描述符集合
& & FD_ZERO(&fdsr); //清除描述符集
& & FD_SET(sock_fd,&fdsr); //把sock_fd加入描述符集
& & //超时的设定
& & tv.tv_sec = 30;
& & tv.tv_usec =0;
& & //添加活动的连接
& & for(i=0;i&MAXCLINE;i++)
& & & & if(fd[i]!=0)
& & & & & & FD_SET(fd[i],&fdsr);
& & //如果文件描述符中有连接请求 会做相应的处理,实现I/O的复用 多用户的连接通讯
& & ret = select(maxsock +1,&fdsr,NULL,NULL,&tv);
& & if(ret &0) //没有找到有效的连接 失败
& & & & perror(&select error!\n&);
& & & & printf(&timeout \n&);
& & //循环判断有效的连接是否有数据到达
& & for(i=0;i&conn_i++)
& & & & if(FD_ISSET(fd[i],&fdsr))
& & & & & & ret = recv(fd[i],buf,sizeof(buf),0);
& & & & & & if(ret &=0) //客户端连接关闭,清除文件描述符集中的相应的位
& & & & & & & & close(fd[i]);
& & & & & & & & FD_CLR(fd[i],&fdsr);
& & & & & & & & fd[i]=0;
& & & & & & & & conn_amount--;
& & & & & & }
& & & & & & & & //否则有相应的数据发送过来 ,进行相应的处理
& & & & & & else
& & & & & & {
& & & & & & & & if(ret &BUF_SIZE)
& & & & & & & & memset(&buf[ret],'\0',1);
& & & & & & & & printf(&client[%d] send:%s\n&,i,buf);
& & & & & & }
& & & & } & & &&
& & if(FD_ISSET(sock_fd,&fdsr))
& & & & new_fd = accept(sock_fd,(struct sockaddr *)&client_addr,&sin_size);
& & & & if(new_fd &=0)
& & & & & & perror(&accept error\n&);
& & & & & &
& & & & if(conn_amount &MAXCLINE)
& & & & { &&
& & & & & & for(i=0;i& MAXCLINE;i++)
& & & & & & {
& & & & & & & & if(fd[i]==0)
& & & & & & & & {
& & & & & & & & & & fd[i] = new_
& & & & & & & & & &
& & & & & & & & } & & & & & & &&
& & & & & & }
& & & & & & conn_amount++;
& & & & & & printf(&new connection client[%d]%s:%d\n&,conn_amount,inet_ntoa(client_addr.sin_addr),n
tohs(client_addr.sin_port));
& & & & & & if(new_fd & maxsock)
& & & & & & {
& & & & & & & & maxsock = new_
& & & & & & } & & & & & & &&
& & & & else
& & & & & & printf(&max connections arrive ,exit\n&);
& & & & & & send(new_fd,&bye&,4,0);
& & & & & & close(new_fd);
& & & & & &
& & showclient();
& & for(i=0;i&MAXCLINE;i++)
& & & & if(fd[i]!=0)
& & & & & & close(fd[i]);
& & exit(0);
//使用select注意事项:
1.要将sock_fd加入到maxfd+1中,要不就无法检测到网络连接,会一直阻塞在select语句
2.通过存储每次连接的描述符,设置FD_SET函数,在遍历的去判断FD_ISSET处理。
3.我们可以看到select每次有数据到来时,需要遍历的去寻找所有可用的描述符,来判断其是否满足处理的条件。
4.select的通知机制,轮询的去查看是否在maxfd+1内有满足条件的描述符。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:82184次
积分:2376
积分:2376
排名:第14620名
原创:134篇
转载:203篇
(2)(2)(1)(8)(5)(15)(7)(21)(4)(1)(3)(2)(2)(28)(64)(43)(32)(18)(1)(10)(4)(13)(6)(8)(3)(4)(2)(2)(1)

我要回帖

更多关于 蓝天模具 的文章

 

随机推荐