基于TCP协议的网络通信

news2024/9/24 13:27:08

        TCP即传输控制协议,基于TCP协议的网络通信总是面向连接的,在通信过程中需要进行“三次握手,四次挥手”,这是众所周知的,所以这里不过多赘述。我们都知道TCP协议传输数据比较稳定,那么为什么稳定,通过本文的代码实现来一探究竟。

        首先来看一下基于TCP协议的网络通信模型:

服务器客户端
创建socket对象创建socket对象

准备通信地址

(端口号+本机IP地址)

准备通信地址

(服务器的公网IP)

绑定socket与通信地址——
设置监听和排队数量——
等待客户端连接连接服务器
分配新的socket对象+开辟新进程或线程——
接收请求发送请求
响应请求接收响应
关闭socket关闭socket

现在有了TCP网络通信模型,那我们按照模型来实现即可,服务器的代码如下:

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

typedef struct sockaddr *SP;

void server(int cli_fd)
{
	char buf[4096];
	size_t buf_size=sizeof(buf);
	while(1)
	{
		//接收请求
		//int ret=read(cli_fd,buf,buf_size);
		int ret=recv(cli_fd,buf,buf_size,0);
		if(ret<=0||0==strcmp("quit",buf))
		{
			printf("客户端%d退出\n",cli_fd);
			break;
		}
		printf("from %d recv:%s bits:%d\n",cli_fd,buf,ret);
		//响应请求
		//把传过来的数据拼接":return"后送回给客户端
		strcat(buf,":return");
		ret=send(cli_fd,buf,strlen(buf)+1,0);
		//ret=write(cli_fd,buf,strlen(buf)+1);
		if(ret<=0)
		{
			printf("客户端%d退出\n",cli_fd);
			break;
		}
	}
	//关闭
	close(cli_fd);
	exit(0);
}

int main(int argc,const char* argv[])
{
	//创建socket
	int sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd<0)
	{
		perror("socket");
		return -1;
	}
	//准备通信地址
	struct sockaddr_in addr={};
	addr.sin_family=AF_INET;
	addr.sin_port=htons(8866);
	addr.sin_addr.s_addr=inet_addr("192.168.110.12");
	socklen_t addrlen=sizeof(addr);
	//绑定
	if(bind(sockfd,(SP)&addr,addrlen))
	{
		perror("bind");
		return -1;
	}
	//监听
	if(listen(sockfd,5))
	{
		perror("listen");
		return -1;
	}
	while(1)
	{
		//等待连接
		struct sockaddr_in src_addr={};
		int cli_fd=accept(sockfd,(SP)&src_addr,&addrlen);
		if(cli_fd<0)
		{
			perror("accept");
			continue;
		}
		//创建进程服务
		if(0==fork())
		{
			server(cli_fd);
		}
	}
		
	return 0;
}

客户端的代码如下:

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

typedef struct sockaddr *SP;

int main(int argc,const char* argv[])
{
	//创建socket
	int cli_fd=socket(AF_INET,SOCK_STREAM,0);
	if(cli_fd<0)
	{
		perror("socket");
		return -1;
	}
	//准备通信地址
	struct sockaddr_in addr={};
	addr.sin_family=AF_INET;
	addr.sin_port=htons(8889);
	addr.sin_addr.s_addr=inet_addr("192.168.110.2");
	socklen_t addrlen=sizeof(addr);
	//连接服务器
	if(connect(cli_fd,(SP)&addr,addrlen))
	{
		perror("connect");
		return -1;
	}

	char buf[4096];
	size_t buf_size=sizeof(buf);
	while(1)
	{
		//发送请求
		printf(">>>>>");
		scanf("%s",buf);
		int ret=send(cli_fd,buf,strlen(buf)+1,0);
		//ret=write(cli_fd,buf,strlen(buf)+1);
		if(ret<=0)
		{
			printf("服务器正在升级,请稍后重试\n");
			break;
		}
		if(0==strcmp("quit",buf))
		{
			printf("通信结束\n");
			break;
		}
		//接收请求
		//int ret=read(cli_fd,buf,buf_size);
		ret=recv(cli_fd,buf,buf_size,0);
		if(ret<=0)
		{
			printf("服务器正在维护,请稍候重试\n");
			break;
		}
		printf("read:%s bits:%d\n",buf,ret);
	}
		
	return 0;
}

下面来运行测试一下双端的通信情况:

over

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

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

相关文章

【Windows 同时安装 MySQL5 和 MySQL8 - 详细图文教程】

卸载 MySQL 参考文章&#xff1a; 完美解决Mysql彻底删除并重装_怎么找到mysql并卸载-CSDN博客使用命令卸载mysql_卸载mysql服务命令-CSDN博客 先管理员方式打开 cmd &#xff0c;切换到 MySQL 安装目录的 bin 文件夹下&#xff0c;执行如下命令&#xff0c;删除 MySQL 服务mys…

基于DPU的OpenStack裸金属服务快速部署及存储解决方案

1 方案背景和挑战 Openstack作为开源云计算领域的领军项目&#xff0c;凭借其强大的功能、灵活的架构以及活跃的社区支持&#xff0c;在全球范围内得到了广泛的采用。通过Openstack&#xff0c;企业和云服务提供商可以更加高效地管理和利用计算资源、存储资源和网络资源&#…

秋招面试准备:《小米2024数字芯片岗面试题》

在数字芯片设计的浪潮中&#xff0c;验证工程师的角色愈发重要。他们如同守门人&#xff0c;确保每一块芯片在投入市场前都能稳定、高效地运行。小米&#xff0c;作为全球知名的智能设备制造商&#xff0c;对数字芯片岗位的人才选拔尤为严格。 本文分享《小米2024数字芯片岗面…

Cat2Bug-Platform报告功能介绍

报告 报告是对团队、项目、测试用例、缺陷、交付物等工作管理做出的总结性报表&#xff0c;目前可通过OPEN API方式创建。 报告列表 报告列表中展示了已经提交的报表信息&#xff0c;点击某一个报告后可查看报告详情&#xff0c;报告可通过markdown格式展示&#xff0c;如下…

Java List初始化的六种方式

在日常的开发中,List作为我们常用的一种数据结构,那么有谁了解过在Java中如何对一个List进行初始化操作。在这些初始化操作中又有哪些遇到的坑呢? 1、常规方式 List<String> languageList = new ArrayList<>(); languageList.add("Java"); language…

C#使用实体类Entity Framework Core操作mysql入门:从数据库反向生成模型

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

如何构建出更好的大模型RAG系统?

ChatGPT爆火之后&#xff0c;以ChatPDF为首的产品组合掀起了知识库问答的热潮。 在过去一整年中&#xff0c;大多数人都在完成RAG系统到高级RAG系统的迭代升级。但是技术发展是迅速的&#xff0c;如何深入了解RAG的发展&#xff0c;做出更好的RAG系统&#xff0c;其实还是非常…

32岁前端干了8年,是继续做前端开发,还是转其它工作_ui设计师转开发

前端发展有瓶颈&#xff0c;变来变去都是那一套&#xff0c;只是换了框架换了环境。换了框架后又得去学习&#xff0c;虽然很快上手&#xff0c;但是那些刚毕业的也很快上手了&#xff0c;入门门槛越来越低&#xff0c;想转行或继续卷&#xff0c;该如何破圈? 这是一位网友的自…

使用SBP打AssetBundle时脚本引用丢失

1&#xff09;使用SBP打AssetBundle时脚本引用丢失 2&#xff09;在UE 5.3中连接Power节点为何10的3次幂等于1009 3&#xff09;如何在Widget中倾斜一张纹理贴图 4&#xff09;如何在打开关卡蓝图时更改游戏模式 这是第401篇UWA技术知识分享的推送&#xff0c;精选了UWA社区的热…

uni-app快速入门

目录 一、什么是 uni-app二、快速创建 uni-app 项目1.创建 uni-app2.运行 uni-app 三、uni-app 相对传统 H5 的变化1.网络模型的变化2.文件类型变化3.文件内代码架构的变化4.外部文件引用方式变化5.组件/标签的变化6.js的变化&#xff08;1&#xff09;运行环境从浏览器变成v8引…

MCU自动测量单元采集振弦式应变计测值的过程

振弦式应变计是一种广泛应用于土木工程、地质勘探等领域的高精度传感器&#xff0c;用于测量结构的应变变化。近年来&#xff0c;随着微控制器单元(MCU)的发展&#xff0c;自动化测量技术得到了极大的提升&#xff0c;使得振弦式应变计的测值采集更加高效和精确。本文将详细介绍…

关于 mybatis-plus-boot-starter 与 mybatis-spring-boot-starter 的错误

不是知道你是否 出现过这样的错误 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): 经过各种度娘&#xff0c;无非就是让你检查三种情况 情况一&#xff1a;mapper.xml没有按照传统的maven架构进行放置 情况二&#xff1a;mybatis的配置信…

C语言实现简单凯撒密码算法

**实验2&#xff1a;传统密码技术 【实验目的】 通过本次实训内容&#xff0c;学习常见的传统密码技术&#xff0c;通过编程实现简单代替密码中的移位密码算法&#xff0c;加深对传统密码技术的了解&#xff0c;为深入学习密码学奠定基础。【技能要求】 分析简单代替密码中的移…

R语言机器学习遥感数据处理与模型空间预测技术及实际项目案例分析

随机森林作为一种集成学习方法&#xff0c;在处理复杂数据分析任务中特别是遥感数据分析中表现出色。通过构建大量的决策树并引入随机性&#xff0c;随机森林在降低模型方差和过拟合风险方面具有显著优势。在训练过程中&#xff0c;使用Bootstrap抽样生成不同的训练集&#xff…

LeetCode 每日一题 ---- 【2207. 字符串中最多数目的子序列】

LeetCode 每日一题 ---- 【2207. 字符串中最多数目的子序列】 2207.字符串中最多数目的子序列方法&#xff1a;贪心 一次遍历 2207.字符串中最多数目的子序列 方法&#xff1a;贪心 一次遍历 从题意中可以看出来&#xff0c;对于 pattern.charAt(0) 一定是插入到最左侧是最优…

什么是SSL证书?它能保护你的网络安全!

相信大家在浏览网页时经常会看到一些网址前面有个“小锁”图标&#xff0c;它代表的网站是安全的&#xff0c;而这背后的秘密就是SSL证书。那SSL证书到底是什么&#xff1f;它有什么用呢&#xff1f; 什么是SSL证书&#xff1f; SSL证书的全称是Secure Sockets Layer证书&…

php发送邮箱教程:如何实现邮件发送功能?

php发送邮箱性能优化策略&#xff1f;怎么使用PHPMail发送邮箱&#xff1f; 无论是用户注册验证、密码重置&#xff0c;还是系统通知&#xff0c;邮件发送都是不可或缺的一部分。AokSend将详细介绍如何使用PHP实现邮件发送功能&#xff0c;帮助开发者快速掌握这一技能。 php发…

高效驱动,掌控动力:TB67H400AFNG 马达驱动器

在如今智能设备和自动化应用领域中&#xff0c;驱动器的性能直接决定了系统的可靠性与效率。东芝的TB67H400AFNG有刷直流马达驱动器凭借其卓越的性能&#xff0c;成为众多行业解决方案中的关键部件。无论是工业控制、自动化设备还是消费类电子产品&#xff0c;TB67H400AFNG都能…

一小时拿下鸿蒙应用开发者高级证书!(二)

鸿蒙应用开发者高级认证&#xff0c;是华为自家研发的硬核操作系统&#xff0c;现在它在市场上的名声也越来越响亮。你手上要是有了鸿蒙的认证小本本&#xff0c;那就等于是掌握了这行里的独门秘籍&#xff0c;找工作的时候&#xff0c;妥妥的加分项。 一个小时刷刷题&#xf…

玩机进阶教程----MTK芯片杂牌机 小品牌机型以及其他mtk设备导出分区的另外一种方法解析

在前面多期博文中都是通过工具来导出分区 制作线刷包的。今天我们以另外一种方法备份系统分区。mtk芯片较多。具体机型适合哪种方法需要自测。多种方法多条思路。遇到机型善用工具。目前一些wifi网卡 点读笔以及有些其他mtk芯片设备。通常分区都较小。可以参考教程 通过教程了…