网络服务器模型

服务器模型

        在服务端中,服务器有一个listen函数。它用于等待客户端连接,把多个客户端放到等待队列当中。而服务器可以有多个连接请求,进行监听,可以取出一个连接请求,然后创建一个通信套接字与一个客户端进行通信(进行与客户端进行一对一通信)。

        服务器(服务端)通常处理多个客户端通信,服务端则需要可以和多个客户端进行通信。

为了能够达到服务端与多个客户端进行通信,服务端程序需要有不同的处理方式

1、循环服务器模型

        一次只与一个客户端进行通信,当与一个客户端通信完成后,再与下一个客户端进行通信。

也就是必须上一个完了才能进行下一个通信,由于listen()监听,则服务端会一直做监听(直到关闭

服务端的监听套接字),不管当前是否是在通信都一直在进行监听,然后只要有连接请求都放在等

待队列。

        实现循环服务器,只需要多次accept从等待队列中获取新的连接请求进行通信,代码如下:
#include <sys/types.h>         
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc,char * argv[])
{
	int serverfd = socket(AF_INET,SOCK_STREAM,0);
	if(serverfd < 0)
	{
		perror("socket error");
		return 0;
	}
	//服务端的ip、port
	struct sockaddr_in serveraddr;
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(9999);
	serveraddr.sin_addr.s_addr = inet_addr("xxx.xxx.xxx.xxx");

	bind(serverfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));

	listen(serverfd,5);//监听套接字,检测客户端的连接,只要有客户端连接,就存放到等待队列

	while(1)
	{
		struct sockaddr_in client;//用于存储客户端地址
		socklen_t len;
		int fd = accept(serverfd,(struct sockaddr *)&client,&len);//阻塞等待等待队列有客户端连接,建立连接,得到客户端

		char buf[20];//通信
		int num;
		while(1)
		{
			bzero(buf,20);
			num = read(fd,buf,20);
			if(num > 0)
			{
				printf("server read ok,data is %s",buf);
			}
			write(fd,"ok\n",4);
			if(strcmp(buf,"quit\n") == 0)
			{
				break;
			}
		}
		close(fd);//关闭与客户端通信
	}
	//服务端不在进行通信,要关闭整个服务端才关闭监听套接字
	close(serverfd);//关闭整个服务端,不能使用tcp,不能监听
	return 0;
}

2、并发服务器模型

        在服务器中,可以进行多个客户端的连接请求,同时进行通信接受一个客户端连接请求

后与客户端进行处理,还可以与其他客户端进行连接,可以同时与多个客户端进行操作。

实现处理多个则需要通过多进程或者多线程来实现,代码如下:

#include <sys/types.h>      
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

int main()
{
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd<0)
    {
        perror("socket error");
        return 0;
    }
    
    struct sockaddr_in serveraddr;
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(9999);
    serveraddr.sin_addr.s_addr = inet_addr("xxx.xxx.xxx.xxx"); 

    bind(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));

    listen(sockfd,5);    //做多5个连接客户端,创建5个等待队列

    while(1)
    {
        struct sockaddr_in clint;
        socklen_t len;
        int fd = accept(sockfd,(struct sockaddr *)&clint,&len);

        if(fork() == 0)
        {
            //操作
        }
        close(fd);
    }
    colse(sockfd)
}

        这两个服务器模型一个是串联工作,一个是并连工作,各有各的优势,不过常用的还是并连的这种。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啵啵520520

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值