C/S模型测试

news2025/1/20 22:04:58

1

1.1代码示例

#include<stdio.h>
#include<stdio.h>

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <arpa/inet.h>

#include <sys/stat.h>
#include <fcntl.h>
    
#include <unistd.h>

#include <string.h>

int main(void)
{
	int sockfd=0;
	int ret=0;
	struct sockaddr_in seraddr;

	char tmpbuff[4096]={"I need some offers"};
	int cnt=0;
	ssize_t nsize=0;

	/* 1 创建网络套接字 */
	sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(-1==sockfd)
	{
		perror("fail to socket");
		return -1;
	}

	/* 2 初始化网络地址结构体 */
	seraddr.sin_family=AF_INET;
	seraddr.sin_port=htons(50000);
	seraddr.sin_addr.s_addr=inet_addr("192.168.1.123");

	/* 3 发送连接请求 */
	ret=connect(sockfd,(struct sockaddr *)&seraddr,sizeof(seraddr));
	if(-1==ret)
	{
		perror("fail to connect");
		return -1;
	}

	/* 4 客户端与服务器交互 */
	while(1)
	{
#if 0
		/* 4.1 清空发送缓冲区 */
		memset(tmpbuff,0,sizeof(tmpbuff));
		/* 4.2 拼接数据 */
		sprintf(tmpbuff,"client send:### %d",cnt);
		cnt++;

		/* 4.3 发送数据到网络套接字 */
		nsize=send(sockfd,tmpbuff,strlen(tmpbuff),0);
		if(-1==nsize)
		{
			perror("fail to send");
			return -1;
		}
#endif

#if 1
		/* 清空接收缓冲区 */
		memset(tmpbuff,0,sizeof(tmpbuff));
		/* 接收网络套接字数据 */
		nsize=recv(sockfd,tmpbuff,sizeof(tmpbuff),0);
		if(-1==nsize)
		{
			perror("fail to recv");
			return -1;
		}
#endif
		
		/* 显示接收数据 */
		printf("client recv:### %s\n",tmpbuff);
	}

	/* 5 关闭网络套接字 */
	close(sockfd);

	return 0;
}



int main(void)
{
    int sockfd=0;
    struct sockaddr_in seraddr;
    int ret=0; 

    int confd=0;
    char tmpbuff[4096]={0};
    ssize_t nsize=0;

    /* 1 创建网络套接字 */
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(-1==sockfd)
    {
        perror("fail to socket");
        return -1;
    }
    
    /* 2 初始化网络地址结构体 */
    seraddr.sin_family=AF_INET;
    seraddr.sin_port=htons(50000);
    seraddr.sin_addr.s_addr=inet_addr("192.168.1.123");

    /* 3 绑定网络套接字 */
    ret=bind(sockfd,(struct sockaddr *)&seraddr,sizeof(seraddr));
    if(-1==ret)
    {
        perror("fail to bind");
        return -1;
    }

    /* 4 监听网络套接字 */
    ret=listen(sockfd,10);
    if(-1==ret)
    {
        perror("fail to listen");
        return -1;
    }

    /* 5 服务器与客户端交互 */
    while(1)
    {
        /* 5.1 创建通信套接字-阻塞等待网络套接字连接请求*/
        confd=accept(sockfd,NULL,NULL);
        if(-1==confd)
        {
            perror("fail to accept");
            return -1;
        }

#if 0
        /* 5.2 清空接收缓冲区 */
        memset(tmpbuff,0,sizeof(tmpbuff));
        /* 5.3 接收通信套接字数据-并做接收完成处理 */
        nsize=recv(confd,tmpbuff,sizeof(tmpbuff),0);
        if(-1==nsize)
        {
            perror("fail to recv");
            return -1;
        }
        else if(0==nsize)
        {
            return 0;
        }
#endif
        
        /* 5.2 清空发送缓冲区 */
        memset(tmpbuff,0,sizeof(tmpbuff));
        /* 5.4 拼接 */
        sprintf(tmpbuff,"server send:### %s",tmpbuff);
        /* 5.5 发送 */
        nsize=send(confd,tmpbuff,strlen(tmpbuff),0);
        if(-1==nsize)
        {
            perror("fail to send");
            return -1;
        }
    }

    /* 6 关闭通信套接字 */
    close(confd);
    /* 7 关闭网络套接字 */
    close(sockfd);

    return 0;
}

1.2运行结果

(1)运行服务器
(2)运行客户端

现象如下:
	客户端发生阻塞

在这里插入图片描述

(1)关闭服务器:
	客户端不阻塞-说明recv函数为非阻塞状态

在这里插入图片描述

总结:
(1)如果将服务器accept函数放在while循环内部:同时运行客户端与服务器,可以发现服务器可以与多个客户端建立连接(解决的问题-服务器并发访问)。
(2)但是只能进行一次数据发送(虽然解决了服务器的并发访问问题,但是对于大量的数据传输却手足无措)
			小意外:当服务器端退出,此时客户端不再阻塞,正常执行函数体。(这就说明了,此时recv函数为非阻塞状态=》那么服务器和客户端同时运行,为什么会发生阻塞?)

补充:
(1)如果将服务器端accept函数放在while循环外部(对比TCP文件传输):
	1)只有一个客户端能够与服务器建立连接并进行数据收发;其它客户端被阻塞,无法与服务器建立连接。(问题:(1)服务器只能与一个客户端建立连接?(2)那么如何解决这个问题?(3)是从服务端解决这个问题,还是从客户端解决这个问题?	先解决问题(3):显然,要解决这个问题肯定是要从服务器端去解决--客户端是向服务器端发起连接请求,那么具体是否能够建立连接,显然是取决于服务器端的意愿和能力;所以,多个客户端向服务器端发起连接请求,能不能实现的关键在于服务器能不能接受多个客户端接入,服务器端是否允许多个客户端接入。	下面再解决问题(2):解决这个问题,其实用一句话来表述就是解决服务器并发访问问题,这个问题后面专项解决,现在只需要明白所面临的问题是服务器并发访问的问题即可。)

(2)如果将connect函数放在循环外部,将accept函数放在循环外部,此时意味着:客户端与服务器端第一次建立连接,可以发送一次数据;发完数据接着进行第二次,第三次。。。连接请求;此时当然是报错!因为同一个网络套接字只能建立一次连接,不能重复建立连接(这是由TCP通信机制决定的);但是这种方式可以将服务器同时与多个客户端建立连接。。。。。。。。。。。。。。总结一下就是:客户端与服务器端要进行多次请求连接-建立连接;那么每进行一次通信,都必须关闭(close)通信套接字(已经建立三次握手,四次挥手连接的套接字confd-accept)。

在这里插入图片描述

问题:
	(1)在客户端或者服务器的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1719450.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

004 仿muduo实现高性能服务器组件_Buffer模块与Socket模块的实现

​&#x1f308;个人主页&#xff1a;Fan_558 &#x1f525; 系列专栏&#xff1a;仿muduo &#x1f339;关注我&#x1f4aa;&#x1f3fb;带你学更多知识 文章目录 前言Buffer模块Socket模块 小结 前言 这章将会向你介绍仿muduo高性能服务器组件的buffer模块与socket模块的实…

12k Star!Continue:Github Copilot 开源本地版、开发效率和隐私保护兼得、丰富功能、LLM全覆盖!

原文链接&#xff1a;&#xff08;更好排版、视频播放、社群交流、最新AI开源项目、AI工具分享都在这个公众号&#xff01;&#xff09; 12k Star&#xff01;Continue&#xff1a;Github Copilot 开源本地版、开发效率和隐私保护兼得、丰富功能、LLM全覆盖&#xff01; &…

CSS--学习

CSS 1简介 1.1定义 层叠样式表 (Cascading Style Sheets&#xff0c;缩写为 CSS&#xff09;&#xff0c;是一种 样式表 语言&#xff0c;用来描述 HTML 文档的呈现&#xff08;美化内容&#xff09;。 1.2 特性 继承性 子级默认继承父级的文字控制属性。层叠性 相同的属性…

Elasticsearch 认证模拟题 - 5

一、题目 .在集群上有一个索引 food_ingredient&#xff0c;搜索需要满足以下要求&#xff1a; 三个字段 manufacturer&#xff0c;name&#xff0c;brand 都能匹配到文本 cake mix高亮 字段 name&#xff0c;并加标签排序&#xff0c;对字段 brand 正序&#xff0c;_score 降…

【Linux】Linux环境基础开发工具_3

文章目录 四、Linux环境基础开发工具2. vim3. gcc和g动静态库的理解 未完待续 四、Linux环境基础开发工具 2. vim vim 怎么批量化注释呢&#xff1f;最简单的方法就是在注释开头和结尾输入 /* 或 */ 。当然也可以使用快捷键&#xff1a; Ctrl v 按 hjkl 光标移动进行区域选择…

VR导航的实现原理、技术优势和应用场景

VR导航通过虚拟现实技术提供沉浸式环境&#xff0c;结合室内定位技术实现精准导航。目前&#xff0c;VR导航已在多个领域展现出其独特的价值和潜力&#xff0c;预示着智能导航系统的未来发展。 一、实现原理 VR导航技术依托于虚拟现实(VR)和室内定位系统。VR技术利用计算机模…

IMU状态预积分代码实现 —— IMU状态预积分类

IMU状态预积分代码实现 —— IMU状态预积分类 实现IMU状态预积分类 实现IMU状态预积分类 首先&#xff0c;实现预积分自身的结构。一个预积分类应该存储一下数据&#xff1a; 预积分的观测量 △ R ~ i j , △ v ~ i j , △ p ~ i j \bigtriangleup \tilde{R} _{ij},\bigtrian…

MySQL基础索引知识【索引创建删除 | MyISAM InnoDB引擎原理认识】

博客主页&#xff1a;花果山~程序猿-CSDN博客 文章分栏&#xff1a;MySQL之旅_花果山~程序猿的博客-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 一&#xff0c;索引用…

数据在内存中的存储<C语言>

导言 在计算机中不同类型的数据在计算机内部存储形式各不相同&#xff0c;弄懂各种数据在计算机内部存储形式是有必要的&#xff0c;C语言的学习不能浮于表面&#xff0c;更要锻炼我们的“内功”&#xff0c;将来在写程序的时候遇见各种稀奇古怪的bug时&#xff0c;也便能迎刃而…

Beamer中二阶导、一阶导数的显示问题

Beamer中二阶导、一阶导数的显示问题 在beamer中表示 f ′ f f′和 f ′ ′ f f′′时发现导数符号距离 f f f很近 \documentclass{beamer} \usepackage{amsmath,amssymb}\begin{document} \begin{frame}\frametitle{Derivative}Derivative:\[f^{\prime}(x) \quad f \quad…

4月啤酒品类线上销售数据分析

近期&#xff0c;中国啤酒行业正处于一个重要的转型期。首先&#xff0c;消费者对高品质啤酒的需求不断增加&#xff0c;这推动了行业向高端化、场景化和社交化的方向发展。精酿啤酒作为这一趋势的代表&#xff0c;其发展势头强劲&#xff0c;不仅满足了消费者对品质化、个性化…

Java集合【超详细】2 -- Map、可变参数、Collections类

文章目录 一、Map集合1.1 Map集合概述和特点【理解】1.2 Map集合的基本功能【应用】1.3 Map集合的获取功能【应用】1.4 Map集合的两种遍历方式 二、HashMap集合2.1 HashMap集合概述和特点【理解】2.2 HashMap的组成、构造函数2.3 put、查找方法2.4 HashMap集合应用案例【应用】…

退出登录后选择记住登录状态回显用户名和密码

项目背景 : react ant 需求 : 退出登录后 , 选择了记住登录 , 回显用户名和密码 ; 未选择记住 , 则不回显用户名和密码 如图注意 : 发现一个鸡肋的问题 , 未勾选退出后 , 还是会回显 , 后来我查看了cookie和自己的逻辑都没问题 , 原来是因为我保存了密码 , 浏览器保存后自动渲…

C# 代码配置的艺术

文章目录 1、代码配置的定义及其在软件工程中的作用2、C# 代码配置的基本概念和工具3、代码配置的实践步骤4、实现代码配置使用属性&#xff08;Properties&#xff09;使用配置文件&#xff08;Config Files&#xff09;使用依赖注入&#xff08;Dependency Injection&#xf…

Echarts 让柱状图在图表中展示,离开X轴

文章目录 需求分析需求 分析 话不多说,直接源码展示 option = {title: {text: Waterfall Chart,subtext: Li

数据隐私重塑:Web3时代的隐私保护创新

随着数字化时代的不断深入&#xff0c;数据隐私保护已经成为了人们越来越关注的焦点之一。而在这个数字化时代的新篇章中&#xff0c;Web3技术作为下一代互联网的代表&#xff0c;正在为数据隐私保护带来全新的创新和可能性。本文将深入探讨数据隐私的重要性&#xff0c;Web3时…

数字孪生技术为何备受各行业青睐?

数字孪生技术近年来在各行业中受到越来越多的重视&#xff0c;这是因为它具备了显著的优势和广泛的应用前景。数字孪生是指利用数字化技术&#xff0c;在虚拟空间中创建一个与现实世界对应的虚拟模型&#xff0c;通过数据的实时交互和反馈&#xff0c;实现对物理实体的模拟和监…

嵌入式Linux复制剪切删除指令详解

指令操作 1. cp 复制指令 a. 用法&#xff1a;cp [ 选项 ] [ 源文件或目录 ] [ 目标文件或目录 ]&#xff1b; b. 用途&#xff1a;用于复制文件或目录&#xff1b; c. 通常情况下&#xff0c;复制的都不是空文件夹&#xff0c;所以直接使用 cp 复制空文件会失败&#xff0…

三体中的冯诺依曼

你叫冯诺依曼&#xff0c;是一位科学家。你无法形容眼前的现态&#xff0c;你不知道下一次自己葬身火海会是多久&#xff0c;你也不知道会不会下一秒就会被冰封&#xff0c;你唯一知道的&#xff0c;就是自己那寥寥无几的科学知识&#xff0c;你可能会抱着他们终身&#xff0c;…

全国产飞腾模块麒麟信安操作系统安全漏洞

1、背景介绍 目前在全国产飞腾模块上部署了麒麟信安操作系统&#xff0c;经第三方机构检测存在以下漏洞 操作系统版本为 内核版本为 openssh版本为 2、openssh CBC模式漏洞解决 首先查看ssh加密信息 nmap --script "ssh2*" 127.0.0.1 | grep -i cbc 可以通过修改/…