TCP特点UDP编程

news2024/9/22 19:32:40

目录

1、tcp协议和udp协议

2、多线程并发和多进程并发:

(1)多进程并发服务端

(2)多进程并发客户端:

3、tcp:

4、粘包

5、UDP协议编程流程

(1)服务器端:

(2)客户端:

6、tcp状态:

7、tcp状态转移图:


1、tcp协议和udp协议

tcp协议:面向连接   可靠   流式服务

udp协议:无连接   不可靠   数据报

根据场景来决定使用什么协议

2、多线程并发和多进程并发:

多线程并发,如果线程出现失误可能导致整个进程失败,多进程互相不影响

(1)多进程并发服务端

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

int socket_init();
void do_run(int c)
{
    while(1)
    {
        char buff[128]={0};
        int num=recv(c,buff,127,0);
        if(num<=0)
        {
            break;
        }
        printf("child read:%s",buff);
        send(c,"ok",2,0);


    }
}
int main()
{
    signal(SIGCHLD,SIG_IGN);//处理僵死进程   一个是忽略信号,一个是wait();
    int sockfd=socket_init();
    if(sockfd==-1)
    {
        printf("socket err\n");
        exit(1);
    }

    while(1)
    {
        struct sockaddr_in caddr;
        int len=sizeof(caddr);
        int c=accept(sockfd,(struct sockaddr*)&caddr,&len);
        if(c<0)
        {
            continue;
        }
        printf("c=%d\n",c);


        pid_t pid=fork();
        if(pid==-1)
        {
            close(c);
            continue;
        }
        if(pid==0)
        {
            close(sockfd);
            do_run(c);
            close(c);
            printf("child exit  pid=%s\n",getpid());
            exit(0);
        }
        close(c);

    }


}
int socket_init()
{
    int sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd==-1)
    {
        return -1;
    }
    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");


    int res=bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if(res==-1)
    {
        return -1;
    }

    res=listen(sockfd,5);
    if(res==-1)
    {
        return -1;
    }
    return sockfd;



}

(2)多进程并发客户端:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.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)
    {
        exit(1);
    }

    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");


    int res=connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if(res==-1)
    {
        printf("connect err\n");
        exit(1);
    }

    while(1)
    {
        char buff[128]={0};
        printf("input\n");
        fgets(buff,128,stdin);
        if(strncmp(buff,"end",3)==0)
        {
            break;
        }
        send(sockfd,buff,strlen(buff),0);

        memset(buff,0,sizeof(buff));
        recv(sockfd,buff,127,0);
        printf("recv=%s\n",buff);
       
        
    }
     close(sockfd);

}

父进程没有关闭链接,子进程close()不会完成四次挥手

3、tcp:

先建立连接TCP三次握手

最后断开,TCP四次挥手

tcp的可靠性是以牺牲了开销为代价的

4、粘包

多次发送的数据被一次性收到了,误以为是一次性收到的

解决办法:让接收的时候能区分出来,用不同的报文、在报文前面描述数据有多大、不连续send

5、UDP协议编程流程

(1)服务器端:

1、创建套接字socket()

2、指定IP和端口bind()

3、接受数据recvfrom()

4、发送数据sendto()

5、关闭close()

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


int main()
{
    int sockfd=socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd==-1)
    {
        return -1;
    }

    struct sockaddr_in saddr,caddr;
    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");

    int res=bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if(res==-1)
    {
        printf("bind err\n");
        exit(1);
    }

    int len=sizeof(caddr);
    while(1)
    {
        char buff[128]={0};
        recvfrom(sockfd,buff,127,0,(struct sockaddr*)&caddr,&len);
        printf("recv=%s\n",buff);
        sendto(sockfd,"ok",2,0,(struct sockaddr*)&caddr,sizeof(caddr));

    }

}

(2)客户端:

1、创建套接字socket()

2、发送sendto()//需要指定对方的IP和端口

3、接收recvfrom()//需要指定对方的IP和端口

4、关闭close()

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

int main()
{
    int sockfd=socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd==-1)
    {
        exit(1);
    }

    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");


    while(1)
    {
        char buff[128]={0};
        printf("input\n");
        fgets(buff,128,stdin);
        if(strncmp(buff,"end",3)==0)
        {
            break;
        }

        sendto(sockfd,buff,strlen(buff),0,(struct sockaddr*)&saddr,sizeof(saddr));

        memset(buff,0,128);
        int len=sizeof(saddr);
        recvfrom(sockfd,buff,127,0,(struct sockaddr*)&saddr,&len);
        printf("recv=%s\n",buff);
 
    }
    close(sockfd);
}

对于udp编程,因为是无连接的,所以可以多个客户端发送,客户端关闭,服务器端不回收到任何数据,服务器端关闭后,对于客户端无影响。

协议不同可以使用同一个端口

6、tcp状态:

只有在握手和挥手的时候回引起TCP协议的变化,稳定收发连接的时候状态时不会发生改变的。

7、tcp状态转移图:

三次握手完成有一个established状态,四次挥手完成有一个time_wait()状态

 

 

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

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

相关文章

JavaEE初阶:Java线程的状态

目录 获取当前线程引用 休眠当前线程 线程的状态 1.NEW 2.TERMINATED 3.RUNNABLE 4.WAITING 5.TIMED_WAITING 6.BLOCKED 多线程的意义 单线程 多线程 获取当前线程引用 public static Thread currentThread(); 这个方法返回当前线程的引用。但是我…

WSL2 Ubuntu20.04 配置 CUDA

前言 本文主要讲解如何在 Widnows 11 环境下的 WSL2&#xff08;Ubuntu20.04&#xff09;配置 CUDA 来启用 GPU 加速&#xff08;本文默认您已经在 Windows 上安装完成 Nvidia CUDA&#xff09; 配置流程 检查驱动 打开 GeForce Experience 检查驱动程序的情况&#xff0c;…

基于 BlockQueue(阻塞队列) 的 生产者消费者模型

文章目录 阻塞队列&#xff08;BlockQueue&#xff09;介绍生产者消费者模型 介绍代码实现lockGuard.hpp&#xff08;&#xff09;Task.hpp&#xff08;任务类&#xff09;BlockQueue.hpp&#xff08;阻塞队列&#xff09;conProd.cc&#xff08;生产者消费者模型 主进程&#…

从来不懂K8s的人10分钟内将应用跑在了K8s中

大家可能都听说过 K8s 或者 docker &#xff0c;可能有容器编排的概念&#xff0c;知道这会提高运维效率&#xff0c;但是由于上手难度高迟迟没有学习它。 今天我以自己的实际经历教大家将自己的应用在10分钟内部署到k8s中&#xff0c;你不需要懂任何的 docker 命令和 k8s 命令…

LinkedList

LinkedList的模拟实现&#xff08;底层是一个双向链表&#xff09;LinkedList使用 LinkedList的模拟实现&#xff08;底层是一个双向链表&#xff09; 无头双向链表&#xff1a;有两个指针&#xff1b;一个指向前一个节点的地址&#xff1b;一个指向后一个节点的地址。 节点定…

STM32单片机实现Bootloader跳转的关键步骤

感谢关注&#xff01; 本期话题 现在越来越多的嵌入式设备支持远程自动升级&#xff0c;不需要再借助下载器。这样对于设备的维护非常方便。 当然若使设备支持远程升级&#xff0c;需要编写支持升级的程序代码&#xff0c;可以称之为 BootLoader。 也就是说&#xff0c;将设…

【二叉树构建与遍历3】先序遍历+后序遍历构建一个满二叉树并输出中序遍历 C++实现

注意&#xff1a;根据先序遍历与后序遍历只有在满二叉树的情况下才能确定一个唯一的树。这里介绍的是根据先序遍历后序遍历构建一个满二叉树并输出中序遍历顺序。 思路&#xff1a; 先来一个例子&#xff1a; 先序遍历序列为&#xff1a;FDXEABG 后序遍历序列为&#xff1a;…

股票委托接口的部分源码分析(一)

对于一些股票委托接口的源码分析需要具体指定的交易系统可能有不同的接口实现。以下是对一个常见的股票委托接口实现的源码分析示例&#xff1a; import requestsdef place_order(symbol, price, quantity, side): url https://example.com/api/place_order payload {…

gRPC 客户端调用服务端需要连接池吗?

发现的问题 在微服务开发中&#xff0c;gRPC 的应用绝对少不了&#xff0c;一般情况下&#xff0c;内部微服务交互&#xff0c;通常是使用 RPC 进行通信&#xff0c;如果是外部通信的话&#xff0c;会提供 https 接口文档 对于 gRPC 的基本使用可以查看文章 gRPC介绍 对于 g…

ClickHouse(二十三):Java Spark读写ClickHouse API

进入正文前&#xff0c;感谢宝子们订阅专题、点赞、评论、收藏&#xff01;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; &#x1f3e1;个人主页&#xff1a;含各种IT体系技术&#xff0c;IT贫道_Apache Doris,大数据OLAP体系技术栈,Kerberos安全认证-CSDN博客 &…

vue开发环境搭建(WebStorm)

一、安装Node.js&#xff0c;搭建Vue环境 1、访问Node.js官网&#xff08;https://nodejs.org/en/download/&#xff09;进行安装包下载。 2、下载成功之后运行安装程序&#xff0c;进行安装。 如果是用安装程序进行安装&#xff0c;在安装过程中会自动进行Nodejs环境变量的配置…

最新两年工作经验总结

最新两年工作经验总结 前言URP的使用1&#xff1a;如何开启URP1、老项目升级为URP2、创建新项目时选择URP创建 2&#xff1a;URP阴影的设置 PolyBrush的使用&#xff08;地图编辑插件&#xff09;制作山峰or低谷边缘柔化雨刷上色制造场景中的物体贴图地形创建容易踩坑的点ProBu…

springboot大文件上传、分片上传、断点续传、秒传的实现

对于大文件的处理&#xff0c;无论是用户端还是服务端&#xff0c;如果一次性进行读取发送、接收都是不可取&#xff0c;很容易导致内存问题。所以对于大文件上传&#xff0c;采用切块分段上传&#xff0c;从上传的效率来看&#xff0c;利用多线程并发上传能够达到最大效率。 …

示例1:FreeRTOS移植详解_基于HAL库工程

1、开发环境 (1)Keil MDK: V5.38.0.0 (2)STM32CubeMX: V6.8.1 (3)MCU: STM32F103C8(F1系列软仿真最方便) (4)ARM编译器&#xff1a;V5(使用V6编译会报错) 2、移植准备工作 (1)用于移植FreeRTOS的基础工程。 时钟已配置好串口已配置好printf已经重定向到串口1 (2)FreeRT…

《YOLO小目标检测》专栏介绍 CSDN独家改进创新实战专栏目录

&#x1f4a1;&#x1f4a1;&#x1f4a1;Yolo小目标检测&#xff0c;独家首发创新&#xff08;原创&#xff09;&#xff0c;适用于Yolov5、Yolov7、Yolov8等各个Yolo系列&#xff0c;专栏文章提供每一步步骤和源码&#xff0c;带你轻松实现小目标检测涨点 &#x1f4a1;&…

【二分查找篇】速刷牛客TOP101 高效刷题指南

文章目录 17、BM17 二分查找-I18、BM18 二维数组中的查找19、BM19 寻找峰值20、BM20 数组中的逆序对21、BM21 旋转数组的最小数字22、BM22 比较版本号23、BM23 二叉树的前序遍历 17、BM17 二分查找-I 思路步骤&#xff1a; step 1&#xff1a;从数组首尾开始&#xff0c;每次取…

wustojc日期格式变化

#include <stdio.h> int main() {char a[10];for(int i0;i<10;i){//用一个耍聪明的方法&#xff0c;全部用数组存储&#xff1b;面向结果编程a[0]getchar();}printf("%c%c%c%c%c%c%c%c%c%c",a[6],a[7],a[8],a[9],a[2],a[0],a[1],a[5],a[3],a[4]);return 0;}…

什么是跳跃表 ? 说一说跳跃表的查询和新增流程 ?

1.什么是跳跃表&#xff08;Skip List&#xff09; 跳跃表是 ZSet 有序列表底层的一种实现&#xff0c;也成为跳表。它通过添加多层链表的方式&#xff0c;用于在有序集合中进行高效的查找操作。 简单跳跃表的结构图&#xff1a; 从图中可以看出跳跃表有这些特征&#xff1a; …

Nginx-URLRewrite伪静态

URLRwrite是指将真实地址隐藏&#xff0c;用户访问是通过伪地址进行访问&#xff0c;这样可以隐藏URL中的传参等等 URLwrite演示&#xff0c;浏览器输入伪URL&#xff0c;回车会跳转到真实URL Rewrite匹配规则 redirect是指当请求伪装地址后&#xff0c;页面会直接跳转到真实…

基于微信小程序的上门维修评价系统_22c7h-

随着科学研究的不断深入&#xff0c;有关上门维修的各种信息量也在成倍增长。面对庞大的信息量&#xff0c;就需要有上门维修系统来提高管理工作的效率。通过这样的系统&#xff0c;我们可以做到信息的规范管理和快速查询&#xff0c;从而减少了管理方面的工作量。 建立基于微信…