【Linux网络】TCP_Socket

news2024/12/25 1:03:00

目录

TCP协议(传输控制协议)

listen状态

accept和connect

TCP_echo_server

(1)创建套接字

(2)绑定

(3)设置listen状态

(4)loop

(5)客户端

多线程远程执行命令


TCP协议(传输控制协议)

传输层协议
有连接
可靠传输(前提网络要联通,复杂,维护性要更强)
面向字节流

tcp和udp在创建套接字和绑定部分是一样的;

不同的是,tcp在服务端绑定后需要将套接字的状态设置为listen状态,除此之外,在通信前要获取新连接;在客户端也要connect;

因为tcp是面向连接的,tcp需要未来不断地能够做到获取连接;

listen状态

accept和connect


  

 


 在TCP(传输控制协议)的服务端中获取新连接是至关重要的,原因如下:

  •  建立连接

TCP是面向连接的协议。客户端发起连接请求(通过 connect 函数),服务端需要接受这些请求(通过 accept 函数)来建立连接。这个连接是双向的通信链路,允许数据在客户端和服务端之间可靠地传输。例如,当你访问一个网站时,你的浏览器(客户端)向Web服务器(服务端)发起TCP连接请求,服务器接受这个请求后,两者之间就建立了一条可靠的通信链路,用于传输网页数据。

  •  并发处理

服务端通常需要同时处理多个客户端的请求。通过获取新连接,服务端可以为每个客户端创建一个独立的连接,从而实现并发处理。例如,一个在线游戏服务器可能需要同时处理成千上万的玩家连接。每个玩家的客户端都会向服务器发起TCP连接请求,服务器接受这些请求并创建对应的连接,这样就能同时为多个玩家提供服务。

  • 数据交互

获取新连接是数据传输的起点。一旦连接建立,客户端和服务端就可以通过读写套接字( read 和 write 函数,或者 recv 和 send 函数)来交换数据。例如,在一个文件传输服务中,客户端请求下载文件,服务端接受连接后,就可以通过已建立的连接将文件数据发送给客户端。
 

TCP_echo_server

下面我们来手动实现一下tcp_echo_server;按照下面的流程来实现:

(1)创建套接字

// 1、创建套接字
_listensockfd = ::socket(AF_INET, SOCK_STREAM, 0);
if (_listensockfd < 0)
{
      LOG(FATAL, "socket error\n");
      exit(SOCKET_ERROR);
}
LOG(DEBUG, "socket create sucess\n");

(2)绑定

struct sockaddr_in local;
memset(&local, 0, sizeof(local));
local.sin_family = AF_INET;
local.sin_port = htons(_port);
local.sin_addr.s_addr = INADDR_ANY;

int n = ::bind(_listensockfd, (struct sockaddr *)&local, sizeof(local));

(3)设置listen状态

// 3、设置套接字为listen状态
// 因为tcp是面向连接的,tcp需要未来不断地能够做到获取连接
int m = listen(_listensockfd, MAXCOUNT);
if (m < 0)
{
     LOG(FATAL, "listen error\n");
}
LOG(INFO, "listen sucess\n");

(4)loop

(1)获取新连接

// 获取新连接
struct sockaddr_in client;
socklen_t len = sizeof(client);
int sockfd = ::accept(_listensockfd, (struct sockaddr *)&client, &len);
if (sockfd < 0)
{
      LOG(WARNING, "accept error\n");
      continue;
}
InetAddr addr(client);
LOG(INFO, "get a new link,client info :%s\n", addr.Addrstr().c_str());

(2)

因为下面的几个版本都需要用的Service函数,我先提前放到这里;

    void Service(int sockfd, InetAddr addr)
    {
        while (true)
        {
            char inbuffer[2048];
            ssize_t n = ::read(sockfd, inbuffer, sizeof(inbuffer) - 1); // 读消息,-1是因为它是系统调用不会做字符串处理
            if (n > 0)
            {
                inbuffer[n] = 0;
                string echo_string = "[server echo]# ";
                echo_string += inbuffer;
                n = ::write(sockfd, echo_string.c_str(), echo_string.size()); // 写消息
            }
            else if (n == 0) // 读到文件结尾,也就是通信结束
            {
                LOG(INFO, "client %s quit\n", addr.Addrstr().c_str());
                break;
            }
            else
            {
                LOG(ERROR, "read server error:%s\n", addr.Addrstr().c_str());
                break;
            }
        }
    }

1、version 0 版本

Service(sockfd, addr);

2、version 1 ----多进程版本

 pid_t id =fork();
if(id==0)
{
::close(_listensockfd);
if(fork()>0)exit(0);//子进程退出
Service(sockfd, addr);//孙进程会造成僵尸进程
exit(0);
}
//father
::close(sockfd);
int n=waitpid(id,nullptr,0);//1、忽略;2、父子孙
if(n>0)
{
LOG(INFO,"wait child sucess\n");
}

3、version 2 ----多线程版本

pthread_t tid;
ThreadDate *td = new ThreadDate(sockfd, this, addr);
pthread_create(&tid, nullptr, Execute, td); // 新线程分离

4、version 3 ---线程池版本

task_t aa=std::bind(&TcpServer::Service,this,sockfd,addr);
ThreadPool<task_t>::GetInstance()->Equeue(aa);

(5)客户端

以上我们就完成了tcp_echo_server,也就是用tcp实现的一个简单的通信;

多线程远程执行命令

这里我们用version 2 多线程版本来实现远程执行命令;

为了使代码更加美观,我们在version2版本的基础上,将Service函数进行封装;将它封装到command.hpp的HandlerCommand函数里面;

这样我们调用回调函数,然后再主函数中进行绑定即可;

using command_server_t =std::function<void(int sockfd, InetAddr addr)>;
void HandlerCommand(int sockfd, InetAddr addr)
{
    while (true)
    {
        char inbuffer[2048];
        ssize_t n = ::recv(sockfd, inbuffer, sizeof(inbuffer) - 1,0); // 读消息,-1是因为它是系统调用不会做字符串处理             
        if (n > 0)
        {
            inbuffer[n] = 0;
            string result = Excute(inbuffer);
            n = ::send(sockfd, result.c_str(), result.size(),0); // 写消息
        }
        else if (n == 0) // 读到文件结尾,也就是通信结束
        {
            LOG(INFO, "client %s quit\n", addr.Addrstr().c_str());
            break;
        }
        else
        {
            LOG(ERROR, "read server error:%s\n", addr.Addrstr().c_str());
            break;
        }
    }
}

完成上面的准备工作,怎么执行命令?

在之前我写过手写shell的文章,可以直接用里面的代码,文章用的是exec*函数来执行命令;但是这里我们用一个更加简单的函数:popen直接执行即可;

string Excute(const string &cmdstr)
{
    FILE *fp=popen(cmdstr.c_str(),"r");
    string result;
    if(fp)
    {
        char line[1024];
        while(fgets(line,sizeof(line),fp))//读文件
        {
            result+=line;
        }
        return result;
    }
    else
    {
        return "execute error";
    }
}

完整代码:

tcp_echo_server:

登录 - Gitee.com

远程执行命令:

登录 - Gitee.com

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

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

相关文章

算法|牛客网华为机试11-20C++

牛客网华为机试 上篇&#xff1a;算法|牛客网华为机试1-10C 文章目录 HJ11 数字颠倒HJ12 字符串反转HJ13 句子逆序HJ14 字符串排序HJ15 求int型正整数在内存中存储时1的个数HJ16 购物单HJ17 坐标移动HJ18 识别有效的IP地址和掩码并进行分类统计HJ19 简单错误记录HJ20 密码验证…

Pandas DataFrame学习补充

1. 从字典创建&#xff1a;字典的键成为列名&#xff0c;值成为列数据。 import pandas as pd# 通过字典创建 DataFrame df pd.DataFrame({Column1: [1, 2, 3], Column2: [4, 5, 6]}) 2. 从列表的列表创建&#xff1a;外层列表代表行&#xff0c;内层列表代表列。 df pd.Da…

剖析高精度、直线电机技术八大常见问题你了解吗?

在现代工业自动化和机械工程的快速发展背景下&#xff0c;高精度直线电机技术逐渐崭露头角&#xff0c;成为推动各类高端设备和系统的重要力量。直线电机以其独特的工作原理和优越的性能特点&#xff0c;广泛应用于数控机床、自动化生产线、机器人等领域。 一、什么是高精度直线…

如何解决RabbitMQ消息的重复消费问题

什么情况下会导致消息的重复消费——在消费者还没成功发送自动确认机制时发生&#xff1a; 网络抖动消费者挂了 解决方案 每条消息设置一个唯一的标识id幂等方案&#xff1a;【Redis分布式锁、数据库锁&#xff08;悲观锁、乐观锁&#xff09;】 面试官&#xff1a;如何解决…

jade 0919 | 提取自TVBox的直播盒子,频道丰富高清

jade电视直播app覆盖央视全频道和各大卫视&#xff0c;各地地方台也能一网打尽&#xff0c;随时随地看高清电视。各卫视台覆盖广泛&#xff0c;包括浙江电视台、湖南卫视、江苏卫视、东方卫视等全部卫视台&#xff0c;最新内容先一步掌握。拥有广东、北京、风云足球等热播体育频…

书生大模型实战营第四期-入门岛第一关

关卡任务 好的&#xff0c;我们废话不多说&#xff0c;开始闯关Go,Go,Go! 闯关任务 SSH连接到本地使用开发机是很舒服的&#xff0c;但是我们该如何连接呢&#xff0c;别急&#xff0c;书生给我们教程了 这里我们展示结果&#xff0c;对了&#xff0c;本地SSH连接需要安装一些…

臻于智境 安全护航 亚信安全受邀出席新华三智算新品发布会

近日&#xff0c;紫光股份旗下新华三集团在北京隆重举办了主题为“乘势 进化 臻于智境”的新华三智算新品发布会。作为新华三集团的长期战略合作伙伴&#xff0c;亚信安全受邀参会&#xff0c;亚信安全CEO马红军出席发布仪式&#xff0c;并与来自各界的业界伙伴共同探讨智能化…

错题收集app有哪些?5个软件帮助你快速进行app收集

错题收集app有哪些&#xff1f;5个软件帮助你快速进行app收集 以下是五款便捷实用的错题收集 App&#xff0c;能够帮助你更高效地记录、整理和复习错题&#xff1a; 试卷全能宝 试卷全能宝 是一款多功能试卷识别和编辑软件&#xff0c;适合用于错题整理和记录。你可以创建错…

GitGraphPro 图管理系统

1.产品介绍 产品介绍方案 产品名称: GitGraphPro 图管理系统 主要功能: 智能图谱构建版本控制与协作数据分析与可视化自定义模板与导出功能介绍: 1. 智能图谱构建 具体作用:GitGraphPro 利用先进的算法,自动从项目数据

flask框架用法介绍(一)

flask框架用法介绍(一) 一、创建flask项目二、创建模板以及简单的前后端数据传递三、在模板中使用条件判断和循环3.1 条件判断3.2 for循环四、模板继承一、创建flask项目 项目框架如下: app.py内容如下: from flask import Flaskapp = Flask(__name__)@app.route("…

[免费]SpringBoot+Vue学生成绩管理系统【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue学生成绩管理系统&#xff0c;分享下哈。 项目视频演示 【免费】SpringBootVue学生成绩管理系统 Java毕业设计_哔哩哔哩_bilibili 项目介绍 随着计算机互联网技术的不断发展&#xff0c;不断…

接口测试(九)jmeter——关联(JSON提取器)

一、JSON提取器介绍 要检查的响应字段&#xff1a;样本数据源引用名称&#xff1a;可自定义设置引用方法&#xff1a;${引用变量名}匹配数字 匹配数字含义-1表示全部0随机1第一个2第二个…以此类推 缺省值&#xff1a;匹配失败时的默认值ERROR&#xff0c;可以不写 二、js…

【MyBatis源码】SqlSessionFactoryBuilder源码分析

文章目录 概述类结构从 InputStream 创建 SqlSessionFactoryXMLConfigBuilder构建ConfigurationXMLConfigBuilder初始化方法parse()方法parseConfiguration属性&#xff08;properties&#xff09; 概述 SqlSessionFactory 是 MyBatis 的核心接口之一&#xff0c;提供创建 Sql…

鸿蒙原生应用开发及部署:首选华为云,开启HarmonyOS NEXT App新纪元

目录 前言 HarmonyOS NEXT&#xff1a;下一代操作系统的愿景 1、核心特性和优势 2、如何推动应用生态的发展 3、对开发者和用户的影响 华为云服务在鸿蒙原生应用开发中的作用 1、华为云ECS C系列实例 &#xff08;1&#xff09;全维度性能升级 &#xff08;2&#xff…

SQLite3库增删改查实现数据管理

1. SQLite3简介 SQLite3是一个轻量级的、嵌入式的关系型数据库管理系统&#xff0c;在保存测序数据或结果等时可使用&#xff0c;简单高效&#xff0c;并且有无需服务器、单文件存储数据、支持标准SQL、支持跨平台等优势。 本文以Sqlite3数据库为基础&#xff0c;创建代码示例…

【实验八】前馈神经网络(4)优化问题

1 参数初始化 模型构建 模型训练 优化 完整代码 2 梯度消失问题 模型构建 模型训练 完整代码 3 死亡Relu问题 模型构建 模型训练 优化 完整代码 1 参数初始化 实现一个神经网络前&#xff0c;需要先初始化模型参数。如果对每一层的权重和偏置都用0初始化&#xff0…

Vscode配置CC++编程环境的使用体验优化和补充说明

文章目录 快速编译运行&#x1f47a;code runner插件方案Code Runner Configuration 直接配置 相关指令和快捷键默认task配置和取消默认 配置文件补充介绍(可选 推荐阅读)&#x1f60a;使用vscode预置变量和环境变量环境变量的使用使用环境变量的好处环境变量可能引起的问题 检…

计算机网络:网络层 —— IPv4 地址与 MAC 地址 | ARP 协议

文章目录 IPv4地址与MAC地址的封装位置IPv4地址与MAC地址的关系地址解析协议ARP工作原理ARP高速缓存表 IPv4地址与MAC地址的封装位置 在数据传输过程中&#xff0c;每一层都会添加自己的头部信息&#xff0c;最终形成完整的数据包。具体来说&#xff1a; 应用层生成的应用程序…

【秋冬进补】灵芝玉叶膏冬令上选减补两不误

秋冬季不仅是进补季&#xff0c;也是肥胖增涨的季节&#xff0c;气温降低了&#xff0c;运动、户外活动量减少了&#xff0c;消耗吸收率减慢&#xff0c;饮食中肉类比例上升&#xff0c;绿蔬少了&#xff0c;油热量增加了&#xff0c;肥胖几率也一样增加了。因此&#xff0c;选…

HTML5 + CSS3 + JavaScript 编程语言学习教程

HTML5 CSS3 JavaScript 编程语言学习教程 欢迎来到这篇关于 HTML5、CSS3 和 JavaScript 的详细学习教程&#xff01;无论你是初学者还是有一定基础的开发者&#xff0c;这篇文章都将帮助你深入理解这三种技术的核心概念、语法和应用。 目录 HTML5 1.1 HTML5 简介1.2 HTML5 …