C/S模型测试

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)在客户端或者服务器的

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringMVC:创建一个简单的SpringMVC框架

目录 一、框架介绍 两个重要的xml文件 SpringMVC执行流程 二、Vscode搭建SpringMVC框架 1、maven创建webapp原型项目 2、pom.xml下添加springmvc的相关依赖 3、在web.xml配置 4、springmvc.xml的配置 5、编写Controller控制器类 6、 编写JSP界面 7、项目结构图 一…

12.RedHat认证-Linux文件系统(下)

12.RedHat认证-Linux文件系统(下) swap虚拟内存 我加一个硬盘做实验sdc # 创建交换分区&#xff08;不用做成逻辑卷也能灵活分区&#xff09; [rootcentos8 ~]# fdisk /dev/sdc -l Disk /dev/sdc&#xff1a;10 GiB&#xff0c;10737418240 字节&#xff0c;20971520 个扇区 …

【监控】prometheus自定义指标 exporter

一、【写在前面】 prometheus自定义指标本质是用代码自己写一个网络访问的采集器&#xff0c;你可以在官网看到&#xff0c;Client libraries | Prometheus官方支持的语言有GO JAVA PYTHON RUBY RUST, 第三方的库就支持的更多了&#xff0c;有BASH C CPP LUA C# JS PHP R PER…

ADuM1201可使用π121U31间接替换π122U31直接替换

ADuM1201可使用π121U31间接替换π122U31直接替换 一般低速隔离通信150Kbps电路可使用π121U31&#xff0c;价格优势较大。速度快的有其它型号可达10M,200M,600M。 本文主要介绍ADUM1201,替换芯片π121U31简单资料请访问下行链接 只要0.74元的双通道数字隔离器&#xff0c;1T1…

智和信通助力中国移动湖南某市分公司县级政府外网运维项目

中国移动湖南某市分公司承建市下属某县政务外网网络建设项目&#xff0c;且在网络建设完工后&#xff0c;承担起运维职责&#xff0c;随着工作的推进市移动公司发现仅靠人力难以高效开展运维工作。 设备类型&#xff1a;OLT、ONU等通信设备 设备品牌&#xff1a;华为、中兴等…

记一次安卓.apk加固,加固后安装失败,重新签名也安装失败问题

1、AndroidStudio打包生成.apk文件 2、使用360加固apk&#xff08;或其他平台&#xff09; 注意&#xff1a;加固后的apk必须进行重新签名才能安装&#xff0c;否则安装失败。apk签名可以使用jarsigner 和 apksigner&#xff0c;jarsigner 只能进行v1签名&#xff1b;apksigner…

【PostgreSQL17新特性之-冗余IS [NOT] NULL限定符的处理优化】

在执行一个带有IS NOT NULL或者NOT NULL的SQL的时候&#xff0c;通常会对表的每一行&#xff0c;都会进行检查以确保列为空/不为空&#xff0c;这是符合常理的。 但是如果本身这个列上有非空&#xff08;NOT NULL&#xff09;约束&#xff0c;再次检查就会浪费资源。甚至有时候…

Git使用规范及命令

文章目录 一、Git工作流二、分支管理三、Git命令操作规范1. 切到develop分支&#xff0c;更新develop最新代码2. 新建feature分支&#xff0c;开发新功能3. 完成feature分支&#xff0c;合并到develop分支4. 当某个版本所有的 feature 分支均合并到 develop 分支&#xff0c;就…

CSS--学习

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

不借助三方平台自主搭建量化回测系统 ——以海龟交易策略为例

数量技术宅团队在CSDN学院推出了量化投资系列课程 欢迎有兴趣系统学习量化投资的同学&#xff0c;点击下方链接报名&#xff1a; 量化投资速成营&#xff08;入门课程&#xff09; Python股票量化投资 Python期货量化投资 Python数字货币量化投资 C语言CTP期货交易系统开…

Vue 2.0使用Vue-count-to给数字添加增长动画

在开发后台管理系统时&#xff0c;时常会遇到数据汇总&#xff0c;为了页面展示更生动&#xff0c;用户体验更好&#xff0c;通常会对汇总的数字加一个逐步递增动画。 实现这个效果一般是用的 Vue-count-to这个插件&#xff0c;这是一款简单好用的一个数字滚动插件&#xff0c;…

前端传String字符串 后端使用enun枚举类出现错误

情况 前端 String 后端 enum 前端 后端 报错 2024-05-31T21:47:40.61808:00 WARN 21360 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to con…

OSPF状态机+SPF算法

OSPF状态机 1.点到点网络类型 down-->init-->(前提为可以建立邻接)exstart——>exchange-->若查看邻接的DBD 目录后发现不用进行LSA 直接进入ful。若查看后需要进行查询、应答先进入loading&#xff0c;在查询应答完后再进入 fuIl: 2.MA网络类型 down --&g…

Linux下配置Pytorch

1.Anaconda 1.1虚拟环境创建 2.Nvidia驱动 3.CUDA驱动安装 4.Pytorch安装 具体的步骤如上&#xff1a;可参考另一位博主的博客非常详细&#xff1a; Linux服务器配置PythonPyTorchCUDA深度学习环境_linux cuda环境配置-CSDN博客https://blog.csdn.net/NSJim/article/detai…

民国漫画杂志《时代漫画》第35期.PDF

时代漫画35.PDF: https://url03.ctfile.com/f/1779803-1248636125-ee3a2b?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps: 资源来源网络!

微信小程序-页面导航-导航传参

1.声明式导航传参 navigator组件的url属性用来指定将要跳转到的页面的路径&#xff0c;同时&#xff0c;路径的后面还可以携带参数&#xff1a; &#xff08;1&#xff09;参数与路径之间使用 ? 分割 &#xff08;2&#xff09;参数键与参数值用 相连 &#xff08;3&…

LeetCode503:下一个更大元素Ⅱ

题目描述 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &#xff09;&#xff0c;返回 nums 中每个元素的 下一个更大元素 。 数字 x 的 下一个更大的元素 是按数组遍历顺序&#xff0c;这个数字之后的第一个比它更大的数&#xff0c;这…

CSwin-PNet 新的医学图像分割网络

很长时间没有看到一些比较传统的医学图像分割网络了&#xff0c;2022年&#xff0c;来自哈尔滨工业大学的研究团队在Expert Systems With Applications. 期刊上发表了题为《CSwin-PNet: A CNN-Swin Transformer combined pyramid network for breast lesion segmentation in ul…

Web前端三大主流框:React、Vue 和 Angular

在当今快速发展的 Web 开发领域&#xff0c;选择合适的前端框架对于项目的成功至关重要。React、Vue 和 Angular 作为三大主流前端框架&#xff0c;凭借其强大的功能和灵活的特性&#xff0c;赢得了众多开发者的青睐。本文将对这三大框架进行解析&#xff0c;帮助开发者了解它们…

二叉树的前序遍历(oj题)

一、题目链接&#xff1a; https://leetcode-cn.com/problems/binary-tree-preorder-traversal/ 二、题目思路 先调用二叉树节点计算函数&#xff0c;得到二叉树的总结点数。然后申请该大小的数组空间。 再使用前序遍历&#xff0c;依次访问每个结点的数据&#xff0c;依次存…