Linux23 --- 三次握手四次挥手、客户端编程流程代码、命令netstat、 tcp协议是个面向链接的可靠的流式服务

news2025/1/18 3:20:18

tcp协议特点:
面向连接的,可靠的,流式服务。
在这里插入图片描述

一、三次握手 、四次挥手

链接的建立通过三次握手,链接的断开通过四次挥手

1、TCP固定头部结构

在这里插入图片描述
在这里插入图片描述

2、三次握手

在这里插入图片描述

3、四次挥手

在这里插入图片描述

二、命令 - netstat -natp

n - 用数字来表示ip地址、端口,而不是用服务名
a - 所有,结果包含监听套接字
t - 显示tcp链接
p - 显示进程的id号

在这里插入图片描述
在这里插入图片描述

三、tcp协议是个面向链接的可靠的流式服务:应答确认,超时重传。

丢了能重发,重复了能去掉。但可能出现先发的后到达的特殊情况,数据传输的路径可能不一样。但存在序号,会进行乱序重排。
在这里插入图片描述
在这里插入图片描述

如何看到发送缓存区还有多少个字节为发送,接收缓存区还有多少个字节未接收?

使用命令 netstat 可以看
netstat -natp

示例:将接收大小改为一字节

 int n = recv(c,buff,127,0);

 int n = recv(c,buff,1,0);

运行结果:
ok的次数会不一样,可以看出send和recv的次数是可以不一样的
在这里插入图片描述

四、客户端编程流程代码

在这里插入图片描述

1、循环进行数据收发

运行结果:

链接成功:
在这里插入图片描述
可以正常进行传输,客户端输入end结束链接
在这里插入图片描述

当多个客户端运行时,只有第一个运行的客户端能正常传输数据,第二个客户端已经链接,但不能正常发送数据,没有机会去接收链接

在这里插入图片描述
服务器端与客户端建立链接之后,套接字c1、c2和客户端sockfd,两边都存在接收和发送缓存区,当执行recv时,是从自身的接收缓存区接收数据,发送时从发送缓存区将数据发送到对方的接收缓存区。所以,send执行成功,只能说其成功将数据成功写入到发送缓存区,是否成功发送,不知道。当写入发送缓存区时,会根据相关底层协议的规定会将其发送到对方计算机描述符对应的接收缓存区中,具体操作根据相关协议要求。
在这里插入图片描述

命令 - netstat -natp

n - 用数字来表示ip地址、端口,而不是用服务名
a - 所有,结果包含监听套接字
t - 显示tcp链接
p - 显示进程的id号

在这里插入图片描述
在这里插入图片描述

tcp协议是个面向链接的可靠的流式服务:应答确认,超时重传。

丢了能重发,重复了能去掉。但可能出现先发的后到达的特殊情况,数据传输的路径可能不一样。但存在序号,会进行乱序重排。
在这里插入图片描述
在这里插入图片描述

如何看到发送缓存区还有多少个字节为发送,接收缓存区还有多少个字节未接收?

使用命令 netstat 可以看
netstat -natp

示例:将接收大小改为一字节

 int n = recv(c,buff,127,0);

 int n = recv(c,buff,1,0);

运行结果:
ok的次数会不一样,可以看出send和recv的次数是可以不一样的
在这里插入图片描述

代码

服务器端 ser.c

一次只能正常链接一个客户端

代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int socket_init();

int main()
{
    int sockfd = socket_init();
    if( sockfd == -1)
    {
        exit(0);
    }

    while( 1 )
    {
        struct sockaddr_in caddr;//记录客户端地址 ip port
        int len = sizeof(caddr);
        int c = accept(sockfd,(struct sockaddr*)&caddr,&len);
        if( c < 0)
        {
            continue;
        }

        printf("accept c = %d\n",c);//accept运行时会阻塞,打印提示有人链接

        while( 1 )
        {
            char buff[128] = {0};
            int n = recv(c,buff,127,0);//也可以使用read,会阻塞

            if( n <= 0)//对方关闭了==,对方出错了<
            {
                break;
            }

            printf("recv = %s\n",buff);
            send(c,"ok",2,0);//也可以使用write
        }
        close(c);//关闭c
        printf("close\n");//表面有一个客户端链接了,并已经关闭链接
    }

    close(sockfd);
}

int socket_init()
{
    //创建一个在传输层使用tcp协议的一个套接字
    int sockfd = socket(AF_INET,SOCK_STREAM,0); //AF_INET --地址zhu,目前的固定的、服务类型 ---- tcp流式服务
    if(sockfd == -1)//创建失败
    {
        return -1;
    }

    //定义一个套接字地址,一个ipv4 专用的地址
    struct sockaddr_in saddr;
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(6000);//网络字节 大端
    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");//将字符串转成无符号整形

    //指定ip端口
    int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if( res == -1)
    {
        printf("bind err\n");
        return -1;
    }

    //创建监听队列
    res = listen(sockfd,5);
    if( res == -1)
    {
        return -1;
    }
    
    return sockfd;

}

客户端 cli.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main()
{
    //和服务器端通讯
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if( sockfd == -1)
    {
        printf("socket err\n");
        exit(0);
    }

    //指定服务器的ip和端口
    struct sockaddr_in saddr;//定义一个套接字的地址,代表服务器的地址
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(6000);//6000代表服务器的端口,系统随机分配自身的端口  1024以内属于知名端口,例如短号110等,只有管理员用户可使用  4096以内为保留端口  一般使用都锁使用4096以上
    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    //发起链接
    //开始三次握手
    int res = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));//如果失败,先检查参数,在考虑端口和ip是否与服务器端匹配,在考虑网络是否有问题,在检查服务器是否启动
    if( res == -1)
    {
        printf("connect failed\n");
        exit(0);
    } 

    //从键盘获取数据
    while(1)
    {
        printf("input : \n");
        char buff[128] = {0};
        fgets(buff,128,stdin);
        if( strncmp(buff,"end",3) == 0)
        {
            break;
        }
        
        //发送数据
        send(sockfd,buff,strlen(buff) - 1,0);
        memset(buff,0,128);//清空
        int n = recv(sockfd,buff,127,0);
        if( n <= 0)//服务器关闭
        {
            break;
        }
        printf("buff = %s\n",buff);
        
    }

    close(sockfd);


}

服务器端 thread.c

//利用线程,实现多个正常链接

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include<pthread.h>
//实现多个客户端链接

int socket_init();

void* fun(void* arg)
{
    int c = (int)arg;
    while(1)
    {
        char buff[128] = {0};
        int n = recv(c,buff,127,0);
        if( n <= 0)
        {
            break;
        }
        printf("buff(%d) = %s\n",c,buff);
        send(c,"ok",2,0);
    }
    close(c);
    printf("close\n");
}

int main()
{
    int sockfd = socket_init();
    if( sockfd == -1)
    {
        exit(0);
    }

    while( 1 )
    {
        struct sockaddr_in caddr;//记录客户端地址 ip port
        int len = sizeof(caddr);
        int c = accept(sockfd,(struct sockaddr*)&caddr,&len);
        if( c < 0)
        {
            continue;
        }

        printf("accept c = %d\n",c);//accept运行时会阻塞,打印提示有人链接:
        //创建一个线程
        pthread_t id;
        pthread_create(&id,NULL,fun,(void*)c);
        //简便的做法,但系统会给警告,整形和指针大小都是4之节,后面再转成整形,这将其看成指针
          
    }
    close(sockfd);
}

int socket_init()
{
    //创建一个在传输层使用tcp协议的一个套接字
    int sockfd = socket(AF_INET,SOCK_STREAM,0); //AF_INET --地址zhu,目前的固定的、服务类型 ---- tcp流式服务
    if(sockfd == -1)//创建失败
    {
        return -1;
    }

    //定义一个套接字地址,一个ipv4 专用的地址
    struct sockaddr_in saddr;
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family = AF_INET;

    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");//将字符串转成无符号整形

    //指定ip端口
    int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if( res == -1)
    {
        printf("bind err\n");
        return -1;
    }

    //创建监听队列
    res = listen(sockfd,5);
    if( res == -1)
    {
        return -1;
    }
    
    return sockfd;

}

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

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

相关文章

【8】【用户操作日志】操作日志SpringBootStarter

操作日志 此版本操作日志主要就是通过AOP拦截器实现的&#xff0c;整体主要分为AOP拦截器、自定义函数、日志上下文、扩展接口&#xff1b;组件提供了6个扩展点&#xff0c;自定义函数、日志上下文、用户信息获取&#xff0c;日志保存&#xff0c;自定义异常获取&#xff0c;入…

2023王道考研数据结构笔记第四章串

第四章 串 4.1 串的定义 4.1.1 串的相关概念 串&#xff1a;即字符串&#xff08;String&#xff09;是由零个或多个字符组成的有限序列。一般记为S‘a1a2…an’ (n>0) 其中S是串名&#xff0c;单引号&#xff08;注&#xff1a;有的地方用双引号&#xff0c;如Java、C&am…

4. Unity之文件资源和其它杂项

1. 资源文件 unity中的Assets文件夹下的文件都可以称为时资源文件&#xff0c;包括模型文件、材质文件、纹理贴图文件、脚本文件、音频文件等&#xff0c;如果想查看某一个文件在电脑中的保存路径&#xff0c;可以选中指定文件后&#xff0c;单击鼠标右键选择show in Explorer…

研究生退税的详细流程

本文介绍在个人所得税软件中&#xff0c;进行退税操作的详细流程。 又到了一年一度的退税时间了。作为研究生&#xff0c;由于每个月都有固定的工资&#xff0c;有时还会有导师发放的补助、国家或院校等发放的奖学金等收入&#xff0c;所以其中有时需要缴纳一部分税款&#xff…

vue-template-admin的keep-alive缓存与移除缓存

一&#xff0c;场景 A页面是表单页面&#xff0c;填写后需要跳转B页面。如果B页面不操作返回的话&#xff0c;应该能还原A页面的内容&#xff0c;而如果B页面点击提交&#xff0c;再回到A页面的时候&#xff0c;应该清除缓存。 二&#xff0c;实现方法 A页面要缓存数据&…

网络互连模型:OSI 七层模型

OSI 七层模型 七层模型&#xff0c;亦称 OSI&#xff08;Open System Interconnection&#xff09;。OSI 七层参考模型是国际标准化组织&#xff08;ISO&#xff09;制定的一个用于计算机或通信系统间网络互联的标准体系&#xff0c;一般称为 OSI 参考模型或七层模型。OSI 七层…

询问new bing关于android开发的15个问题(前景、未来、发展方向)

前言&#xff1a;new bing是基于chat-gpt的新搜索工具&#xff0c;可以采用对话方式进行问题搜索&#xff0c;经过排队等候终于可以使用new bing&#xff0c;询问了目前我最关心的关于android开发几个问题 文章目录1.如何学好android开发&#xff1f;2.android开发能做什么?3.…

最近爆火的ChatGPT核心技术演进历程

文章目录1.前言2.初识ChatGPT2.1.什么是ChatGPT2.2.ChatGPT和其他模型对比具有的特性3.ChatGPT技术演进历程3.1.Transformer&#xff08;转移学习&#xff09;和基础模型3.2.GPT-1&#xff1a;简化模型&#xff0c;使其更适合自然语言生成3.2.1.什么是GPT-13.2.1.GPT-1的优势3.…

3.crypto-config.yaml配置文件分析和cryptogen工具使用[fabric2.2]

在fabric网络启动的过程中&#xff0c;会使用使用cryptogen 工具创建组织的证书文件&#xff0c;这时候就会用到crypto-config.yaml配置文件&#xff0c;例如fabric官方测试例程test-network中就用到了crypto-config-org1.yaml&#xff0c;crypto-config-org2.yaml&#xff0c;…

java实例解析类图中【关联、组合和聚合】的区别

总目录链接==>> AutoSAR入门和实战系列总目录 文章目录 聚合Composition聚合与组合的区别关联是两个独立类之间的关系,它通过它们的对象建立关联。关联可以是一对一、一对多、多对一、多对多。在面向对象的编程中,一个对象与另一个对象通信以使用该对象提供的功能和服…

轮盘赌选择法

轮盘赌选择原理 轮盘赌选择法&#xff08;roulette wheel selection&#xff09;是最简单也是最常用的选择方法&#xff0c;在该方法中&#xff0c;各个个体的选择概率和其适应度值成比例&#xff0c;适应度越大&#xff0c;选中概率也越大。 从图中可以看出一等奖、二等奖、…

Rust学习总结之数组,元组,结构体用法

学过数据结构的都知道有这么一个公式&#xff0c;程序数据结构算法&#xff0c;好的数据结构能大大降低算法设计的复杂度&#xff0c;也能更好的为算法服务。了解一门新的计算机编程语言其数据结构是必须首先要学的&#xff0c;这有利于对该语言的理解和快速上手。本文将对Rust…

vue引入cdn Vue 优化Vue引入 cdn vue cdn Vue优化引入CDN vue 项目 CDN优化

vue引入cdn Vue 优化Vue引入 cdn vue cdn Vue优化引入CDN vue 项目 CDN优化未引入 CDN前 main.js更改CDN方式引入在 vue.config 中引入 CDNindex.html 加载 cdn资源使用CDN引入资源后的main.js如果引入CDN后 组件不生效CDN 服务商推荐未引入 CDN前 main.js // 依赖使用 npm 方…

Windows server 2003怎么安装iis?Windows server 2003安装IIS教程

Windows 2008系统服务器安装IIS之前已经分享过了&#xff0c;和Windows 2003完全不同&#xff0c;今天飞飞将详细地和你分享Windows server 2003卸载和安装IIS的步骤方法&#xff0c;希望可以帮助到你~ 1、首先进入服务器&#xff0c;确定下服务器是否有安装IIS&#xff0c;有…

漫谈数据库表设计及索引设计

一.数据库表设计 在数据库表设计上有个很重要的设计准则&#xff0c;称为范式设计。 什么是范式设计&#xff1f; 范式来自英文Normal Form&#xff0c;简称NF。MySQL是关系型数据库&#xff0c;但是要想设计—个好的关系&#xff0c;必须使关系满足一定的约束条件&#xff0c…

论如何用C语言的数组手撕一棵特殊的完全二叉树----堆

目录 0.前言 1. 用数组表示存储一棵完全二叉树 2. 数组表示的完全二叉树的性质 3. 堆的基本概念 3.1 堆的核心性质 3.2 堆顶的性质 3.3 堆的单支性质 3.4 堆的左右支关系 4. 用代码实现堆 4.1 堆类的实现 4.2 堆的初始化 4.3 堆的销毁 4.4 获取堆顶的数据 4.5 …

这款 Python 工具进行数据分析及数据可视化真的很棒啊

前言 大家好&#xff0c;今天我们以全国各地区衣食住行消费数据为例&#xff0c;来分析2022年中国统计年鉴数据&#xff0c;统计全国各地人民的消费地图&#xff0c;看看&#xff1a; 哪个省份的人最能花钱 哪个省份的人最舍得花钱 哪个省份的人最抠门 全国各地区人民在吃、穿…

一文读懂SpringBoot整合Elasticsearch(一)

&#xff08;本篇文章主要介绍Spring Boot如何整合Elasticsearch&#xff0c;包括基本配置、数据操作、搜索功能等方面。&#xff09; 一、前言 Elasticsearch是一款全文搜索引擎&#xff0c;可用于快速、准确地存储、搜索和分析大量数据。而Spring Boot是一款快速开发框架&a…

JUC【Callable、ReentrantLock、Semaphore、CountDownLatch】

JUC > java.util.concurrent JUC标准库提供的多线程安全相关的包 Callable 接口声明带返回值的任务 类似于Runnable,都是用来描述这个线程的工作的。 Callable描述的任务带返回值&#xff0c;Runnable描述的任务不带返回值 区别&#xff1a;线程封装了一个 “返回值”&#…

【项目精选】基于网络爬虫技术的网络新闻分析(视频+论文+源码)

点击下载源码 基于网络爬虫技术的网络新闻分析主要用于网络数据爬取。本系统结构如下&#xff1a; &#xff08;1&#xff09;网络爬虫模块。 &#xff08;2&#xff09;中文分词模块。 &#xff08;3&#xff09;中3文相似度判定模块。 &#xff08;4&#xff09;数据结构化存…