目录
bit --> type --> kilobite
8 1024
select 可恶!!!
//select
fd_set //位图数组
void FD_CLR(int fd,fd_set *set);
int FD_ISSET(int fd,fd_set* set); //检查文件描述符 fd 是否在 set 中设置
void FD_SET(int fd,fd_set* set) //将文件描述符 fd 加入到 set 中,以便将其监视
void FD_ZERO(fd_set * set)
int select (int nfds,fd_set *readfd,fd_set* writefds,fd_set *exceptfds,
struct timeval *timeout);
___(maxfd+1,num/NULL,num/NULL,num/NULL,NULL(无限制等待));
一对多聊天室 select:(抄抄抄
//sel_kai.c
#include <func.h>
#define IP1 "192.168.235.128"
#define PORT1 8080
int main()
{
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT1);
addr.sin_addr.s_addr=inet_addr(IP1);
int listener=socket(AF_INET,SOCK_STREAM,0);
int ret=bind(listener,(struct sockaddr*)&addr,sizeof(struct sockaddr));
if(ret==-1){error(1,errno,"bind");}
ret=listen(listener,100);
int ac_fd[100];
int ac_num=0; //xuyao监听的文件描述符数量
char buff[256];
char buff_sent[256];
fd_set readfds; //监听集合
FD_ZERO(&readfds);
FD_SET(listener,&readfds); //listener加入监听
int fd_max=listener; //监听的最大文件描述符
fd_set old_fds=readfds; //要监听的文件描述符(专一!!!)
printf("Listening\n");
while(1){
readfds=old_fds;
select(fd_max+1,&readfds,NULL,NULL,NULL);
if(FD_ISSET(listener,&readfds)){
ac_fd[ac_num]=accept(listener,NULL,NULL);
FD_SET(ac_fd[ac_num],&old_fds);
if(ac_fd[ac_num]>fd_max){
fd_max=ac_fd[ac_num];
}
ac_num++;
printf("wellcome user:%d,\n",ac_fd[ac_num-1]);
}
for(int i=0;i<ac_num;i++){
if(FD_ISSET(ac_fd[i],&readfds)){
int a=recv(ac_fd[i],buff,256,0);
if(a==0){close(ac_fd[i]);}
sprintf(buff_sent,"user%d:%s",ac_fd[i],buff);
for(int j=0;j<ac_num;j++){
send(ac_fd[j],buff_sent,strlen(buff_sent)+1,0);
}
}
}
}
return 0;
}
//sel_kai_c.c
#include <func.h>
#define PORT1 8080
#define IP1 "192.168.235.128"
int main()
{
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT1);
addr.sin_addr.s_addr=inet_addr(IP1);
int fd=socket(AF_INET,SOCK_STREAM,0);
int ret=connect(fd,(struct sockaddr*)&addr,sizeof(struct sockaddr));
if(ret==-1){error(1,errno,"bind");}
fd_set readfds;
fd_set old_fds;
int fd_max;
FD_ZERO(&readfds);
fd_max=STDIN_FILENO;
FD_SET(fd,&readfds);
if(fd_max<fd){fd_max=fd;}
char buff[256];
old_fds=readfds;
while(1){
readfds=old_fds;
select(fd_max+1,&readfds,NULL,NULL,NULL);
if(FD_ISSET(STDIN_FILENO,&readfds)){
fgets(buff,256,stdin);
send(fd,buff,strlen(buff)+1,0);
}
if(FD_ISSET(fd,&readfds)){
int n=recv(fd,buff,256,0);
if(n==0){error(1,errno,"connect break");}
printf("%s\n",buff);
}
}
return 0;
}
牛逼极了但是我十分迷惑,应该是有输出的吧???但是没跑出来喵
最怕人类开始思考
————————————————client.c
✗ 46 ---addr
47 socket connect (fd)
48
49 readfds old_fds fd_max buff[]
50
51 FD_SET(fd,&readfds);
✗ 52 while(1){
53 readfds=old_fds;
54 select(fd_max+1,&readfds,NULL,NULL,NULL);
55 if(FD_ISSET(STDIN_FILENO,&readfds)){
56 fgets; send;
57 }//stdin是否有读入
58 if(FD_ISSET(fd,&readfds)){
59 recv; printf;
60 }//fd是否有传输
61
62 }
————————————————server.c
✗ 57 --addr
58 socket --> bind --> listen (listener)
59
60 --ac_fd[] ac_num buff[] buff_sent[]
61 已连接描述符集合 当前监听数量 缓冲数组
62 --readfds old_fds fd_max
63 需要监听的fd 初始需要监听的fd 最大的fd
64
65 FD_SET(listener,&readfds);
✗ 66 while(1){
67 readfds=old_fds;
68 select //监视文件描述符中套接字的变化
69 if(FD_ISSET(listener,&readfds)){
70 accept --> FD_SET //接收,设置监视
✗ 71 (ac_fd[] ac_num fd_max old_fds) //更新信息
72 }//开哥!说,有新链接来的时候就是,listener的读缓冲区
73 //有东西喵,监听到读事件发生???就不阻塞了
74 //我怎么一分钟过去就又迷惑了,好好好,不敢冒头了
75 for(int i=0;i<ac_num;i++){
76 if(FD_ISSET(ac_fd[i],&readfds)){
77 recv,if (recv)==0--close,buff[]-->buff_sent[]
78 }//接收,根据字符数目判断是否断开
79 for(int j=0;j<ac_num;j++){
80 send(buff_sent[])
81 }
82 }
83 }
/*
想起来了喵,bind是 addr & fd 绑定
要把服务器的端口(addr)暴露给客户端,但是客户端的端口是随机分配的
绑定之后,addr就可以通过fd接收数据了,所以!!!
if(FD_ISSET(listener,&readfds))
*/
聪明小辉聪明小辉聪明小辉聪明小辉聪明小辉聪明小辉聪明小辉聪明小辉聪明小辉聪明小辉聪明小辉
补一对一的 select 喵:(抄抄抄
————————————————client.c
--addr
socket --> connect (clientfd)
--rdset buff[]
while(1){
FD_SET(clientfd,&rdset)
FD_SET(STDIN_FILENO,&rdset)
select
if(FD_ISEET(STDIN_FILENO,&rdset))
{ read; send; }
if(FD_ISEET(clientfd,&rdset))
{ recv; printf; }
}
close
————————————————server.c //我猜的,好像没抄过一对一的服务器,问题不大
--addr
socket --> bind --> listen (fd)
--rdset buff[]
if(FD_ISEET(STDIN_FILENO,&rdset))
{ read; send; }
if(FD_ISEET(fd,&rdset))
{ recv; printf; }
}
close