计算机网络_服务器端只能处理一个客户端_模型

版权声明:私藏源代码是违反人性的罪恶行为!博客转载无需告知,学无止境。 https://blog.csdn.net/qq_41822235/article/details/83904602

一、 需要知道

1.1 套接字

套接字是通信端点的抽象。套接字描述符类似于文件描述符。

accept recv阻塞运行

int listen(int sockfd, int size);  早期版本size含义是服务器能维护的已完成的连接和正在连接的队列的大小,有两个队列。新版本的含义是已完成的连接的队列的大小。

1.2 通信流程

图1-1 服务器端模型

图1-2 客户端模型

二、 服务器端

#include<sys/socket.h>	//socket()  bind() listen() accept() 
#include<netinet/in.h>	//因特网地址结构
#include<string.h> //memset()
#include<stdio.h> //printf()
#include<arpa/inet.h> //inet_addr()
#include<assert.h> //assert()

int main()
{
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);   //创建套接字
    assert(-1 != sockfd);
    
    struct sockaddr_in ser, cli;    //套接字地址
    memset(&ser, 0, sizeof(ser));

    ser.sin_family = AF_INET;	//指定地址族 IPV4因特网域
    ser.sin_port = htons(6000);	//指定端口号 6000
    ser.sin_addr.s_addr = inet_addr("127.0.0.1");//指定服务器ipv4地址

    //将套接字和地址关联
    int res = bind(sockfd, (struct sockaddr*)&ser, sizeof(ser)); 
    assert(-1 != res);// 出错原因 地址错误 端口号被占用或者无权使用

    listen(sockfd, 5);	//愿意接受5个连接请求    启动监听  并不具体处理 不阻塞!!!
    
    while(1) //循环处理客户端请求
    {
	    int len = sizeof(cli);
	    int c = accept(sockfd, (struct sockaddr*)&cli, &len);
	    if(c < 0)
	    {
	        printf("error\n");
	        continue;
	    }
	    while(1) //循环接收客户端输入
	    {
	        char recvbuf[128] = {'\0'};
	        int n = recv(c, recvbuf, 127, 0); //有效字节数最多为127
	        if(n <= 0)
	        {
	    	    printf("one client break\n");
		        break;
	        }
	        printf("%d: %s\n", c, recvbuf); //打印从客户端获取的输入
	        send(c, "OK", 2, 0); //向客户端发送回执 提示符OK
	    }
	    close(c);   //关闭用于处理客户端请求的套接字
    }
    close(sockfd); //关闭服务器端
}

三、 客户端

#include<sys/socket.h>	//socket()  bind() listen() accept() 
#include<netinet/in.h>	//因特网地址结构
#include<string.h> //memset()
#include<stdio.h> //printf()
#include<arpa/inet.h> //inet_addr()
#include<assert.h> //assert()

int main()
{
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    assert(-1 != sockfd);

    struct sockaddr_in ser, cli;
    memset(&ser, 0, sizeof(ser));

    ser.sin_family = AF_INET;
    ser.sin_port = htons(6000);
    ser.sin_addr.s_addr = inet_addr("127.0.0.1");
    int res = connect(sockfd, (struct sockaddr*)&ser, sizeof(ser)); //连接服务器
    assert(-1 != res);
    
    while(1)
    {
	    printf("please imput: ");
	    fflush(stdout);
	    char buf[128] = {'\0'};
	    fgets(buf, 128, stdin);
	    buf[strlen(buf)-1] = '\0';  //覆盖结尾的'\n'
	    if(0 == strncmp(buf, "end", 3)) //规定输入end时,客户端结束
	    {
	        break;
	    }
	    send(sockfd, buf, 127, 0); //发送消息
        
        //用于接收服务器端的回执
	    char arr[3] = {'\0'};
	    recv(sockfd, arr, 2, 0);
	    printf("%s\n", arr);
    }
}

四、 运行结果

图2 运行结果

猜你喜欢

转载自blog.csdn.net/qq_41822235/article/details/83904602