###select 实现客户端
#include<myhead.h>
#define IP "192.168.125.100"
#define PORT 8888
int main(int argc, const char *argv[])
{
int cfd=socket(AF_INET,SOCK_STREAM,0);
if(cfd == -1)
{
perror("create socket");
return -1;
}
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=inet_addr(IP);
sin.sin_port=htons(PORT);
if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin)) ==-1)
{
perror("bind error");
return -1;
}
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(cfd,&readfds);
FD_SET(0,&readfds);
char buf[128];
char rbuf[128];
int res=0;
int count;
fd_set tempfds;
while(1)
{
tempfds=readfds;
res=select(cfd+1,&tempfds,NULL,NULL,NULL);
if(res == -1)
{
perror("select error");
return -1;
}else if(res == 0)
{
printf("time out\n");
return -1;
}
if(FD_ISSET(0,&tempfds))
{
memset(buf,0,sizeof(buf));
fgets(buf,sizeof(buf),stdin);
send(cfd,buf,sizeof(buf),0);
printf("发送成功\n");
}
if(FD_ISSET(cfd,&tempfds))
{
memset(rbuf,0,sizeof(buf));
count=recv(cfd,rbuf,sizeof(rbuf),0);
if(count==0)
{
printf("服务器已经下线\n");
break;
}
printf("收到信息:%s\n",rbuf);
}
}
return 0;
}
###POLL实现客户端
#include<myhead.h>
#define PORT 8888
#define IP "192.168.111.26"
struct fdIndex{
int newfd;
int index;
struct sockaddr_in cin2;
};//存储newfd、索引与newfd对应的地址信息结构体
int main(int argc, const char *argv[])
{
int sfd=socket(AF_INET,SOCK_STREAM,0);
if(sfd==-1)
{
perror("create socket");
return -1;
}
int reuse=1;
if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1)
{
perror("reues");
return -1;
}
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=inet_addr(IP);
sin.sin_port=htons(PORT);
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("bind error");
return -1;
}
if(listen(sfd,128)==-1)
{
perror("listen");
return -1;
}
struct sockaddr_in cin;
socklen_t slen=sizeof(cin);
int newfd=-1;
struct pollfd fds[128];
struct fdIndex info[128];//用来存储下标的结构体
for(int i=0;i<128;i++)
{
info[i].newfd=-1;
info[i].index=-1;
}//初始化结构体
fds[0].fd=0;
fds[0].events = POLLIN;
fds[1].fd=sfd;
fds[1].events= POLLIN;
int len=2;
int index;
int maxfd=0;
char rbuf[128];
int index2;
int arrnum=2;
int res;
while(1)
{
res=poll(fds,arrnum,-1);
if(res<0)
{
perror("poll error");
return -1;
}else if(res == 0)
{
perror("timeout\n");
return -1;
}
for(int i=1;i<=len;i++)
{
if(fds[i].revents!=POLLIN)continue;
if( i == 1)
{
if((newfd=accept(sfd,(struct sockaddr*)&cin,&slen))==-1)
{
perror("accept error");
return -1;
}
info[len].newfd=newfd;//记录下newfd
info[len].index=len;//记录下此时newfd存储在fds数组中的下标
info[len].cin2=cin;//赋值地址信息结构体
fds[len].fd=newfd;
fds[len].events=POLLIN;
len++;//表长度加一
arrnum++;
printf("[%s:%d]链接成功,newfd=%d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd);
}else{
memset(rbuf,0,sizeof(rbuf));
res=recv(fds[i].fd,rbuf,sizeof(rbuf),0);
if(res == 0)
{
printf("客户端下线\n");
close(fds[len].fd);
for(int j=0;i<128;i++)
{
if(info[j].newfd==fds[i].fd)
{
index2=info[j].index;
}
}
for(int i=index2;i<len;i++)
{
fds[i]=fds[i+1];
}
len--;//表长度减少1
arrnum--;
}
for(int j=0;j<128;j++)
{
if(info[j].newfd==fds[i].fd)
{
printf("[%s:%d]:%s\n",inet_ntoa(info[j].cin2.sin_addr),\
ntohs(info[j].cin2.sin_port),rbuf);
break;
}
}
}
}
}
return 0;
}
~