使用IO多路复用实现TCP并发服务器

TCP服务器端、客户端实现收发
cs
#include <head.h>
//tcp服务器端
#define SER_PORT 8888 //服务器端口号
#define SER_IP "192.168.144.131" //服务器IP
int main(int argc, const char *argv[])
{
//创建套接字文件描述符
int sfd = socket(AF_INET,SOCK_STREAM,0);
if(sfd == -1 ) //判断是否创建成功
{
perror("sfd error");
return -1;
}
printf("sfd=%d\n",sfd); //输出用于连接的套接字文件描述符
//端口号重启用
int reuse = 1;
if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1)
{
perror("setsockopt errror");
return -1;
}
printf("端口号重启用\n");
//定义一个结构体sin来绑定文件描述符与端口号/IP
//
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(SER_PORT);
sin.sin_addr.s_addr=inet_addr(SER_IP);
//绑定
if(bind(sfd,(struct sockaddr *)&sin,sizeof(sin))==-1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
//将套接字设为被动监听
if(listen(sfd,128)==-1)
{
perror("listen error");
return -1;
}
printf("listen success\n");
//定义一个对端结构体来接收客户端IP、端口号
struct sockaddr_in cin;
socklen_t addrlen=sizeof(cin);
//阻塞状态,等待其他客户端连接
int newfd=accept(sfd,(struct sockaddr *)&cin,&addrlen);
if(newfd==-1)
{
perror("newfd error");
return -1;
}
printf("[%s:%d]-连接成功:newfd=%d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd);
//实现数据的收发
char buf[128]="";
while(1)
{
bzero(buf,sizeof(buf));
int res=recv(newfd,buf,sizeof(buf),0);
if(res==0)
{
printf("客户端下线\n");
close(newfd);
break;
}
printf("[%s:%d]发送:%s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),buf);
strcat(buf,"*_*");
send(newfd,buf,sizeof(buf),0);
printf("发送成功\n");
}
close(sfd);
return 0;
}
cs
#include <head.h>
//tcp客户端
#define SER_PORT 8888 //服务器端口号
#define SER_IP "192.168.144.131" //服务器IP
#define KH_PORT 7777 //客户端端口号
#define KH_IP "192.168.144.131" //客户端IP
int main(int argc, const char *argv[])
{
//创建一个套接字文件描述符
int cfd=socket(AF_INET,SOCK_STREAM,0);
if(cfd==-1)
{
perror("cfd error");
return -1;
}
printf("cfd=%d\n",cfd);
//定义结构体cin来绑定套接字文件描述符与端口号/IP的绑定
struct sockaddr_in cin;
cin.sin_family=AF_INET;
cin.sin_port=htons(KH_PORT);
cin.sin_addr.s_addr=inet_addr(KH_IP);
//端口号重应用
int reuse=1;
if(setsockopt(cfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1)
{
perror("setsockopt error");
return -1;
}
printf("端口重启用\n");
//绑定套接字文件描述符
if(bind(cfd,(struct sockaddr *)&cin,sizeof(cin))==-1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
//定义一个用来接收对端IP、端口号的结构体sin
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(SER_PORT);
sin.sin_addr.s_addr=inet_addr(SER_IP);
//与服务器进行连接
if(connect(cfd,(struct sockaddr *)&sin,sizeof(sin))==-1)
{
perror("connect error");
return -1;
}
printf("connect success\n");
//进行数据的收发
char buf[128]="";
while(1)
{
bzero(buf,sizeof(buf));
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1]=0;
if(strcmp(buf,"quit")==0)
{
printf("客户端断开连接\n");
break;
}
send(cfd,buf,sizeof(buf),0);
bzero(buf,sizeof(buf));
int res=recv(cfd,buf,sizeof(buf),0);
if(res==0)
{
printf("服务器下线\n");
break;
}
printf("服务器发送:%s\n",buf);
printf("接收成功\n");
}
close(cfd);
return 0;
}

UDP服务器端、客户端实现收发
cs
#include <head.h>
//udp服务器端
#define SER_IP "192.168.144.131"
#define SER_PORT 8888
int main(int argc, const char *argv[])
{
int sfd=socket(AF_INET,SOCK_DGRAM,0);
if(sfd==-1)
{
perror("sfd error");
return -1;
}
printf("sfd=%d\n",sfd);
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(SER_PORT);
sin.sin_addr.s_addr=inet_addr(SER_IP);
if(bind(sfd,(struct sockaddr *)&sin,sizeof(sin))==-1)
{
printf("bind error");
return -1;
}
printf("bind success\n");
char buf[128]="";
struct sockaddr_in cin;
socklen_t addrlen=sizeof(cin);
while(1)
{
bzero(buf,sizeof(buf));
recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr *)&cin,&addrlen);
printf("[%s:%d]发送:%s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),buf);
strcat(buf,"*_*");
sendto(sfd,buf,sizeof(buf),0,(struct sockaddr *)&cin,sizeof(cin));
printf("发送成功\n");
}
close(sfd);
return 0;
}
cs
#include <head.h>
#define SER_IP "192.168.144.131"
#define SER_PORT 8888
int main(int argc, const char *argv[])
{
int cfd=socket(AF_INET,SOCK_DGRAM,0);
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=inet_addr(SER_IP);
sin.sin_port=htons(SER_PORT);
socklen_t addrlen =sizeof(sin);
char buf[128]="";
while(1)
{
bzero(buf,sizeof(buf));
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1]=0;
if(strcmp(buf,"quit")==0)
{
printf("退出\n");
break;
}
sendto(cfd,buf,sizeof(buf),0,(struct sockaddr *)&sin,addrlen);
printf("发送成功\n");
recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr *)&sin,&addrlen);
printf("[%s:%d]-发送:%s\n",inet_ntoa(sin.sin_addr),ntohs(sin.sin_port),buf);
}
close(cfd);
return 0;
}
