TCP SELECT 服务器
#include <myhead.h>
#define IP "192.168.174.130"
#define PORT 8080
int main(int argc, const char *argv[])
{
//创建套接字文件描述符
int sfd = socket(AF_INET,SOCK_STREAM,0);
if(sfd == -1)
PRI_ERR("socket err");
//bind绑定服务器的IP和PORT
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
PRI_ERR("bind err");
//设置sfd为监听模式
if(listen(sfd,648)==-1)
PRI_ERR("listen err");
//创建select中的监听文件描述符结构体
fd_set readfds,tempfds;
FD_ZERO(&readfds);
FD_ZERO(&tempfds);
FD_SET(0,&readfds);
FD_SET(sfd,&readfds);
int maxfds = sfd;
int nfd = -1;
char sendbuf[128] = "";
char recvbuf[128] = "";
struct sockaddr_in cin;
socklen_t addlen = sizeof(cin);
while(1)
{
//select监听事件发生
tempfds = readfds;
int ret = select(maxfds+1,&tempfds,NULL,NULL,NULL);
if(ret==-1)
{
perror("select err");
continue;
}
//循环判断i是否是文件描述符集合中的数
for(int i=0; i<=maxfds; i++)
{
if(!FD_ISSET(i,&tempfds))
continue;
//走到这说明是集合中的文件描述符
//输入事件
if(i==0)
{
int sndfd = -1;
bzero(sendbuf,sizeof(sendbuf));
scanf("%d %s",&sndfd,sendbuf);
while(getchar()!='\n');
if(send(sndfd,sendbuf,sizeof(sendbuf),0)==-1)
{
perror("send err");
continue;
}
printf("send success");
}
//有新的客户端连接
else if(i == sfd)
{
nfd = accept(sfd,(struct sockaddr*)&cin,&addlen);
if(nfd == -1)
{
perror("accept err");
continue;
}
//将nfd加入集合
FD_SET(nfd,&readfds);
printf("%s:%d 客户端已上线\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
//如果新的nfd是最大的fd,就要更新maxfds
maxfds = nfd>maxfds?nfd:maxfds;
}
//客户端接收输出消息
else
{
bzero(recvbuf,sizeof(recvbuf));
int ret = recv(i,recvbuf,sizeof(recvbuf),0);
if(ret == 0)
{
printf("%s:%d 客户端已下线\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
close(i);
FD_CLR(i,&readfds);
//删除后也要更新maxfds
while(!FD_ISSET(maxfds,&readfds)&&maxfds-->0);
}
printf("接收到消息:%s\n",recvbuf);
}
}
}
close(sfd);
return 0;
}
TCP SELECT 客户端
#include <myhead.h>
#define PORT 8888
#define IP "192.168.174.130"
int main(int argc, const char *argv[])
{
//select创建套接字
int cfd = socket(AF_INET,SOCK_STREAM,0);
if(cfd == -1)
PRI_ERR("socket err");
//connect 连接服务器
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)
PRI_ERR("connect err");
//创建文件描述符集合
fd_set readfds,tempfds;
FD_ZERO(&readfds);
FD_ZERO(&tempfds);
FD_SET(0,&readfds);
FD_SET(cfd,&readfds);
char sendbuf[128] = "";
while(1)
{
//selet监听事件发生
tempfds = readfds;
int ret = select(cfd+1,&tempfds,NULL,NULL,NULL);
if(ret == -1)
{
perror("select err");
continue;
}
//输入事件
if(FD_ISSET(0,&tempfds))
{
bzero(sendbuf,sizeof(sendbuf));
scanf("%s",sendbuf);
printf("输入是:%s\n",sendbuf);
//发送数据
if(send(cfd,sendbuf,sizeof(sendbuf),0)==-1)
{
perror("send err");
break;
}
printf("发送成功\n");
}
//发送/接收数据事件
if(FD_ISSET(cfd,&tempfds))
{
//接收数据
bzero(sendbuf,sizeof(sendbuf));
int ret = recv(cfd,sendbuf,sizeof(sendbuf),0);
if(ret == -1)
{
perror("recv err");
continue;
}
else if(ret == 0)
{
printf("服务器下线\n");
break;
}
printf("接收到数据%s\n",sendbuf);
}
}
close(cfd);
return 0;
}