TCPselect服务端
#include "head.h"
#define PORT 2580
#define IP "192.168.124.32"
int IN(void);
int Accept(int sfd,struct sockaddr_in cin[],fd_set *readfds,int *maxfd);
int deal_msg(int i,struct sockaddr_in cin[],fd_set *readfds,int *maxfd);
int main(int argc, const char *argv[])
{
//创建流式套接字
int sfd = socket(AF_INET,SOCK_DGRAM,0);
if(sfd < 0)
{
ERR_MSG("socket");
return -1;
}
printf("socket create success sfd =%d\n",sfd);
//允许端口快速复用
int reuse = 1;
if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) < 0)
{
ERR_MSG("setsockopt");
return -1;
}
printf("setsockopt success\n");
//填充地址信息结构体给bind函数使用
//真实地址信息结构体根据地址族指定:AF_INET man 7 ip
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)) < 0)
{
ERR_MSG("bind");
return -1;
}
printf("bind success\n");
//将套接字转换为被动监听状态
if(listen(sfd,128) < 0)
{
ERR_MSG("listen");
return -1;
}
printf("listen success\n");
struct sockaddr_in Pcin[1024-3];
int s_res = 0;
int maxfd;
maxfd = sfd;
//存储文件描述符集
fd_set readfds,tempfds;
FD_ZERO(&readfds);
FD_SET(0,&readfds);
FD_SET(sfd,&readfds);
while(1)
{
tempfds = readfds;
s_res = select(maxfd+1,&tempfds,NULL,NULL,NULL);
if(s_res < 0)
{
ERR_MSG("select");
return -1;
}
else if(0 == s_res)
{
printf("time out\n");
break;
}
for(int i=0;i <= maxfd;i++)
{
if(FD_ISSET(i,&tempfds) == 0)
continue;
if(0 == i)
{
printf("触发键盘输入事件\n");
IN();
else if(i == sfd)
{
Accept(sfd,Pcin,&readfds,&maxfd);
}
else
{
printf("触发客户端交互事件\n");
deal_msg(i,Pcin,&readfds,&maxfd);
}
}
}
}
close(sfd);//关闭套接字
return 0;
}
int IN(void)
{
char buf[128]="";
ssize_t res = 0;
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1] = 0;
printf("%s\n",buf);
return 0;
}
int Accept(int sfd, struct sockaddr_in save[],fd_set *readfds,int *maxfd)
{
int newfd;
struct sockaddr_in cin;
socklen_t addrlen = sizeof(cin);
printf("触发客户端连接事件\n");
newfd = accept(sfd,(struct sockaddr *)&cin ,&addrlen);
if(newfd < 0)
{
ERR_MSG("accept");
return -1;
}
save[newfd -3] = cin;
printf("IP = %s PORT = %d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
FD_SET(newfd,readfds);
*maxfd = *maxfd>newfd?*maxfd:newfd;
return newfd;
}
int deal_msg(int i,struct sockaddr_in cin[],fd_set *readfds,int *maxfd)
{
//接收数据
char buf[128] = "";
ssize_t res = 0;
res = recv(i,buf,sizeof(buf),0);
if(res < 0)
{
ERR_MSG("recv");
return -1;
}
else if(0 == res)
{
printf("IP = %s PORT = %d 客户端下线\n",inet_ntoa(cin[i-3].sin_addr),ntohs(cin[i-3].sin_port));
close(i);
FD_CLR(i,readfds);
while(!FD_ISSET(*maxfd,readfds) && *maxfd--> = 0);
return 0;
}
printf("IP = %s PORT = %d:%s\n",inet_ntoa(cin[i-3].sin_addr),ntohs(cin[i-3].sin_port),buf);
//发送数据
strcat(buf,"*_*");
if(send(i,buf,sizeof(buf),0) < 0)
{
ERR_MSG("send");
return -1;
}
printf("send success\n");
}
TCPselect客户端
#include "head.h"
#define PORT 2580
#define IP "192.168.124.32"
int main(int argc, const char *argv[])
{
//创建流式套接字
int sfd = socket(AF_INET,SOCK_DGRAM,0);
if(sfd < 0)
{
ERR_MSG("socket");
return -1;
}
printf("socket create success sfd =%d\n",sfd);
//填充地址信息结构体给bind函数使用
//真实地址信息结构体根据地址族指定:AF_INET man 7 ip
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
int s_res;
ssize_t res;
char buf[128] = "";
//存储文件描述符集
fd_set readfds,tempfds;
FD_ZERO(&readfds);
FD_SET(sfd,&readfds);
FD_SET(0,&readfds);
while(1)
{
tempfds = readfds;
s_res = select(maxfd+1,&tempfds,NULL,NULL,NULL);
if(s_res < 0)
{
ERR_MSG("select");
return -1;
}
else if(0 == s_res)
{
printf("time out\n");
return -1;
}
if(FD_ISSET(0,&tempfds))
{
printf("触发发送事件\n");
fgets(buf,sizeof(buf),stdin);
ssize_t res = 0;
buf[strlen(buf) - 1] = 0;
if(0 == strcmp(buf,"quit"))
{
printf("客户端退出\n");
break;
}
if(send(sfd,buf,sizeof(buf),0) < 0)
{
ERR_MSG("send");
break;
}
printf("send success\n");
}
if(FD_ISSET(sfd,&tempfds))
{
printf("触发接收事件\n");
bzero(buf,sizeof(buf));
res = recv(sfd,buf,sizeof(buf),0);
printf("%s\n",buf);
if(res < 0)
{
ERR_MSG("ERR_MSG");
break;
}
else if(0 == res)
{
printf("[IP:%s PORT:%d]服务器下线\n",IP,PORT);
break;
}
}
}
close(sfd);//关闭套接字
return 0;
}