Linux网络编程——循环服务器和并发服务器


前言

1、在网络通信中,服务器端通常需要处理多个客户端,总体上采用两种模型来实现:循环服务器和并发服务器。
2、循环服务器是指服务器端依次处理每个客户端,直到当前客户端处理完毕,再处理下一个客户端
3、并发服务器是指服务器采用多任务机制(多进程或多线程),分别为每个客户端创建一个任务来处理


一、TCP下的循环服务器

1、工作流程:
(1)服务器端从连接请求队列中提取请求,建立连接并返回新的已连接套接字
(2)服务器端通过已连接套接字循环接收数据,处理并发送给客户端,直到客户端关闭连接
(3)服务器端关闭已连接的套接字,返回步骤1

//服务器端//
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
	char buf[100]={0};//缓冲区
	int n;
	int fd=socket(AF_INET,SOCK_STREAM,0);//建立套接字
	struct sockaddr_in myaddr;//定义addr结构体
	myaddr.sin_family=AF_INET;
	myaddr.sin_port=htons(8888);//端口号
	myaddr.sin_addr.s_addr=htonl(INADDR_ANY);//自定义ip地址
	int ret=bind(fd,(struct sockaddr*)&myaddr,sizeof(myaddr));//绑定ip地址和端口号
	listen(fd,5);//设置连接数量
	while(1)
	{
		int newfd=accept(fd,NULL,NULL);//收到连接后返回连接好后的描述符
		while((n=recv(fd,buf,sizeof(buf),0))>0)
		{
			printf("buf is %s\n",buf);
			send(newfd,buf,sizeof(buf),0);//发送数据
		}
		printf("client is closed\n");
		close(newfd);//关闭连接描述符
	}
	close(fd);//关闭套接字描述符
}

//客户端//
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
int main(int argc,char *argv[])
{
	int fd=socket(AF_INET,SOCK_STREAM,0);
	struct sockaddr_in youraddr;
	youraddr.sin_family=AF_INET;
	youraddr.sin_port=htons(atoi(argv[1]));
	youraddr.sin_addr.s_addr=inet_addr(argv[2]);
	connect(fd,(struct sockaddr *)&youraddr,sizeof(youraddr));//发送链接请求
	printf("连接成功!\n");
	char buf[100];
	while(1)
	{
		scanf("%s",buf);
		send(fd,buf,sizeof(buf),0);
		recv(fd,buf,sizeof(buf),0);
		printf("ret is %s\n",buf);
	}
	close(fd);
}

二、TCP下的并发服务器

1、工作流程:
(1)服务器端主进程从连接请求队列中提取请求,建立连接并返回新的已连接套接字
(2)服务器端主进程创建线程为客户服务。客户端关闭连接时,子进程结束
(3)服务器端主进程关闭已连接套接字,返回步骤1

//服务器端//
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
void *recv_fun(void *p)
{
	int fd=*(int *)p;
	while(1)
	{
		char buf[100];
		if(recv(fd,buf,sizeof(buf),0)<=0)
			break;
		printf("buf is %s\n",buf);
		send(fd,buf,sizeof(buf),0);
	}
}
int main()
{
	int fd=socket(AF_INET,SOCK_STREAM,0);
	struct sockaddr_in myaddr;
	myaddr.sin_family=AF_INET;
	myaddr.sin_port=htons(8888);
	myaddr.sin_addr.s_addr=htonl(INADDR_ANY);
	int ret=bind(fd,(struct sockaddr*)&myaddr,sizeof(myaddr));
	listen(fd,5);
	while(1)
	{
		pthread_t id;//定义线程变量
		int newfd=accept(fd,NULL,NULL);
		printf("new client %d\n",newfd);
		pthread_create(&id,NULL,recv_fun,&newfd);//创建新线程
	}
	close(fd);
}


//客户端//
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
int main(int argc,char *argv[])
{
	int fd=socket(AF_INET,SOCK_STREAM,0);
	struct sockaddr_in youraddr;
	youraddr.sin_family=AF_INET;
	youraddr.sin_port=htons(atoi(argv[1]));
	youraddr.sin_addr.s_addr=inet_addr(argv[2]);
	connect(fd,(struct sockaddr *)&youraddr,sizeof(youraddr));
	printf("连接成功!\n");
	char buf[100];
	while(1)
	{
		scanf("%s",buf);
		send(fd,buf,sizeof(buf),0);
		recv(fd,buf,sizeof(buf),0);
		printf("ret is %s\n",buf);
	}
	close(fd);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值