UDP/TCP循环服务器

循环服务器:
单任务完成服务众多客户端的请求,待服务的客户端需排队等待服务。
优点: 简单、轻量、易于实现。
缺点: 服务效率不高,无法同时服务多个请求。一旦有客户端恶意占用服务时间,会导致排队的客户端无法接受服务。(基于UDP的echo服务器。)

(1)UDP 循环服务器
框架:

服务器端:             
socket();
bind();
recvfrom();
sendto();
close();
客户端:
socket();
sendto();
recvfrom();
close();

代码实例(客户端发送请求,内容为TIME的字符串,服务器端进行判断后,将时间反馈给客户端。)
客户端代码:

#include
#include
#include
#include
#include
#include
#include
#include

#define SERVER_PORT 8888 //设置端口号
#define BUFF_SIZE 1024

int main(int argc, const char *argv[])
{	
	int sockfd;//创建服务器套接字文件描述符
	struct sockaddr_in server;//本地地址
	char buff[BUFF_SIZE];//收发数据缓冲区
	int n=0;//接收字符串长短
	socklen_t len=0;//本地地址长度

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);//创建UDP套接字
	
	/*初始化地址*/
	memset(&server,0,sizeof(server));//清零
	server.sin_family=AF_INET;//AF_INET协议族
	server.sin_addr.s_addr=htonl(INADDR_ANY);//任意地址
	server.sin_port=(SERVER_PORT);//服务器端口号

	memset(buff,0,BUFF_SIZE);//清零
	strcpy(buff,"TIME");//复制发送字符串

	/*发送数据*/
	if((sendto(sockfd,buff,strlen(buff),0,(struct sockaddr*)&server,sizeof(server)))==-1)
	{
	perror("fail to sento");
	exit(1);
	}

	memset(buff,0,BUFF_SIZE);//清零

	/*接收数据*/
	len=sizeof(server);
	
	n=recvfrom(sockfd,buff,BUFF_SIZE,0,(struct sockaddr*)&server,&len);
	if(n>0)
	{
	printf("TIME:%s",buff);//打印消息
	}
	close(sockfd);
	return 0;
}

服务器端代码:

#include
#include
#include
#include
#include
#include
#include
#include

#define SERVER_PORT 8888
#define BUFF_SIZE 1024


int main(int argc, const char *argv[])
{
	int sockfd;//服务器套接字文件描述符
	struct sockaddr_in local,to;//本地地址信息和发送方地址信息
	char buff[BUFF_SIZE];//收发数据缓存区
	int n=0;
	time_t now;//时间
	socklen_t len=sizeof(to);//发送方地址长度

	sockfd=socket(AF_INET,SOCK_DGRAM,0);//建立UDP套接字

	memset(&local,0,sizeof(local));//清零
	local.sin_family=AF_INET;//AF_INET协议族
	local.sin_addr.s_addr=htonl(INADDR_ANY);//任意本地地址
	local.sin_port=(SERVER_PORT);//服务器端口

	/*将套接字文件描述符绑定到本地地址和端口号*/
	if((bind(sockfd,(struct sockaddr*)&local,sizeof(local)))==-1)
	{
	perror("fail to bind");
	exit(1);
	}

	while(1)
	{
	memset(buff,0,BUFF_SIZE);//清零
	n=recvfrom(sockfd,buff,BUFF_SIZE,0,(struct sockaddr*)&to,&len);//接收发送方数据

	if(n>0&&!strncmp(buff,"TIME",4))//判断是否合法
	{
	memset(buff,0,BUFF_SIZE);//清零
	now=time(NULL);//获取时间
	sprintf(buff,"%24s\r\n",ctime(&now));//将时间复制如缓冲区

	sendto(sockfd,buff,strlen(buff),0,(struct sockaddr*)&to,len);//发送数据
	}
	}
	close(sockfd);
	return 0;
}

(2)TCP循环服务器
框架:

客户端
socket();
connect();
send();
recv();
close();

服务器端
socket();
bind();
listen();
accept();
recv();
send();
close();

代码实例(与UDP相同)
客户端:

#include
#include
#include
#include
#include
#include
#include
#include

#define SERVER_PORT 8889
#define BUFF_SIZE 1024

int main(int argc, const char *argv[])
{	
	int sockfd;//服务器套接字文件描述符
	struct sockaddr_in server;//本地地址
	char buff[BUFF_SIZE];//收发数据缓存区
	int n=0;//接收字符串长度

	/*建立TCP套接字*/
	sockfd = socket(AF_INET, SOCK_STREAM, 0);//建立TCP套接字
	
	/*初始化地址*/
	memset(&server,0,sizeof(server));//清零
	server.sin_family=AF_INET;//AF_INET协议族
	server.sin_addr.s_addr=htonl(INADDR_ANY);//任意本地地址
	server.sin_port=(SERVER_PORT);//服务器端口
	
	/*连接服务器*/
	connect(sockfd,(struct sockaddr*)&server,sizeof(server));
	memset(buff,0,BUFF_SIZE);//清零
	strcpy(buff,"TIME");//复制发送的字符串

	/*发送数据*/
	if((send(sockfd,buff,strlen(buff),0))==-1)
	{
	perror("fail to sent");
	exit(1);
	}

	memset(buff,0,BUFF_SIZE);//清零

	/*接收数据*/
	n=recv(sockfd,buff,BUFF_SIZE,0);
	if(n>0)
	{
	printf("TIME:%s",buff);
	}
	close(sockfd);
	return 0;
}

服务器端:

#include
#include
#include
#include
#include
#include
#include
#include

#define SERVER_PORT 8889//端口地址
#define BUFF_SIZE 1024
#define BACKLOG 5//监听队列长度


int main(int argc, const char *argv[])
{
	int sockfd,connfd;//sockfd为服务器socket描述符,connfd为客户端的socket描述符
	struct sockaddr_in local,to;//本地地址
	char buff[BUFF_SIZE];//收发数据缓存区
	int n=0;
	time_t now;//时间
	socklen_t len=sizeof(to);//

	/*建立TCP套接字*/
	sockfd=socket(AF_INET,SOCK_STREAM,0);

	/*设置服务器地址*/
	memset(&local,0,sizeof(local));
	local.sin_family=AF_INET;
	local.sin_addr.s_addr=htonl(INADDR_ANY);
	local.sin_port=(SERVER_PORT);

	/*绑定地址结构到套接字描述符*/
	if((bind(sockfd,(struct sockaddr*)&local,sizeof(local)))==-1)
	{
	perror("fail to bind");
	exit(1);
	}

	/*设置监听*/
	listen(sockfd,BACKLOG);

	while(1)
	{
	/*接收客户端连接*/
	connfd=accept(sockfd,(struct sockaddr*)&to,&len);	
	memset(buff,0,BUFF_SIZE);
	
	/*接收发送发数据*/
	n=recv(connfd,buff,BUFF_SIZE,0);

	if(n>0&&!strncmp(buff,"TIME",4))
	{
	memset(buff,0,BUFF_SIZE);
	now=time(NULL);
	sprintf(buff,"%24s\r\n",ctime(&now));
	send(connfd,buff,strlen(buff),0);
	}
	close(connfd);
	}
	close(sockfd);
	return 0;
}

你可能感兴趣的:(Linux网络编程)