网络编程(第二章: TCPUDP基础模型)

news2024/10/4 8:11:01

TCP/UDP(服务器、客户端源码)

[(12条消息) 网络编程(4.7作业)(TCP/UDP源代码)_m0_37565374的博客-CSDN博客]:

一. 套接字 socket

1.概念

  1. 最早的socket和消息队列、共享内存,管道一致只能实现一台主机中的多个进程间通信。后期加入了TCP/IP 使得socket支持不同主机的进程间通信。
  2. socket也是一个函数,返回值是一个文件描述符。

image-20230410141427582

2. socket函数(创建套接字)

功能:在内核空间中创建两个缓冲区:接收缓冲区,发送缓冲,用户空间可以接收到两块空间的文件描述符
原型:

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);

参数:

  • int domain:指定协议族(地址族)

    NamePurposeMan page
    AF_UNIX, AF_LOCAL局域网unix(7)
    AF_INETipv4ip(7)
    AF_INET6ipv6ipv6(7)
  • int type:

    SOCK_STREAM字节流式套接字:默认指定TCP协议
    SOCK_DGRAM数据报式套接字:默认指定UDP协议
    SOCK_RAW原始套接字,协议需要在第三个参数指定;
  • int protocol:指定协议; 默认协议填0;

    • IPPROTO_TCP tcp协议
    • IPPROTO_UDP udp协议;

返回值:

  • 成功,返回维护缓冲区的文件描述符,套接字文件描述符;
  • 失败,返回-1,更新errno;

二. TCP

1. TCP模型图

image-20230410143239498

image-20230410143247617

2. TCP搭建相关函数

2.1 socket函数(创建套接字)(同上)

2.2 bind(绑定套接字)

功能:将IP和端口绑定到套接字上
原型:

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

参数:

  • int sockfd:指定要绑定到哪个套接字上,填对应文件描述符;

struct sockaddr*addr:通用地址信息结构体,真实的地址信息结构体根据地址族指定;
                    指定需要绑定到套接字上的IP和端口
--AF_INET--man 7 ip----
   struct sockaddr_in {
       sa_family_t    sin_family; /* address family: AF_INET */     必须填AF_INET;
       in_port_t      sin_port;   /* port in network byte order */  端口号的网络字节序,1024~49151
       struct in_addr sin_addr;   /* internet address */            本机IP地址的网络字节序
                                                                   终端输入:ifconfig查看本机IP
   };
/* Internet address. */
struct in_addr {
   uint32_t       s_addr;     /* address in network byte order */
};

  • socklen_t addrlen:真实的地址信息结构体的大小:sizeof(struct sockaddr_in);

返回值:

  • 成功,返回0;
  • 失败,返回-1,更新errno;

2.3 listen(设置被动监听模式)

功能:将套接字设置为被动监听状态,监听是否有客户端连接成功;
原型:

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);

参数:

  • int sockfd:指定将哪个套接字设置为被动监听状态; socket函数的返回值;
  • int backlog:指定未完成连接队列的容量; 允许同时多少个客户端处于未完成连接状态。 一般填128
    内核会维护两个队列:未完成连接的队列,已完成连接的队列;

返回值:

  • 成功,返回0;
  • 失败,返回-1,更新errno;

2.4 accept(获取客户信息)

功能:阻塞函数,从已完成连接的队列头中获取一个客户端信息,生成一个新的文件描述符
该文件描述符才是与客户端通信的文件描述符!!

原型:

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

参数:

  • int sockfd:被设置为被动监听状态的文件描述符;

  • struct sockaddr *addr:通用地址信息结构体,真实的地址信息结构体根据地址族指定;
    存储连接成功的客户端的地址信息。如果不想获取,则填NULL;

  • socklen_t *addrlen:真实的地址信息结构体的大小,注意是指针类型,需要在外部定义普通变量,赋值后取地址;
    如果第二个参数填NULL,则当前参数填NULL;

返回值:

  • 成功,返回新的文件描述符,该文件描述符用于与客户端通信;
  • 失败,返回-1,更新errno;

2.5 recv(接收数据)

功能:从指定的套接字文件描述符中,接收数据
原型:

#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);

参数:

  • int sockfd:指定要从哪个文件描述符中获取数据,填accept函数获取到的新的文件描述符;

  • void *buf:该指针指向的内存空间中存储获取到的数据,可以是任意类型数据;

  • size_t len:指定要接收的数据大小,以字节为单位;

  • int flags:
    0:阻塞方式接收,当没有数据的时候阻塞;
    MSG_DONTWAIT:非阻塞;

返回值:

  • >0 , 成功,返回成功接收到的字节数;
  • =0, 对端关闭,返回0;
  • =-1, 函数运行失败,更新errno;

2.6 send(发送消息)

功能:通过套接字文件描述符,向指定套接字发送数据;
原型:

#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);

参数:

  • int sockfd:指定要向哪个文件描述符发送数据,填accept函数获取到的新的文件描述符;

  • void *buf:指定要发送的数据首地址,可以是任意类型数据;

  • size_t len:指定要发送的数据大小,以字节为单位;

  • int flags:
    0:阻塞方式发送,当数据满的时候阻塞;
    MSG_DONTWAIT:非阻塞;

返回值:

  • 成功,返回成功发送的字节数;
  • 失败,返回-1,更新errno;

2.7 connect(连接服务器)

功能:通过服务器的IP和端口,连接指定服务器;
原型:

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

参数:

  • int sockfd:指定要将哪个套接字与服务器连接;

  • struct sockaddr *addr:通用地址信息结构体,真实的地址信息结构体根据地址族指定;
    指定要连接的服务器所绑定的IP和端口;

  • socklen_t addrlen:真实的地址信息结构体的大小:sizeof(struct sockaddr_in);

返回值:

  • 成功,返回0;
  • 失败,返回-1,更新errno;

二. UDP

1.UDP模型图

image-20230411115540104

2.UDP搭建相关函数

2.1 socket(创建套接字)(同上)

2.2 bind(绑定套接字)(同上)

bind报错:

  1. bind: Address already in use ===>端口号被占用
  2. bind: Cannot assign requested address ===》IP地址错误,不是本机IP

2.3 recvfrom(接受数据)

功能:从指定套接字中接收数据,同时可以接收到该数据包从哪个发送方发送过来的
原型:

#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, 
				struct sockaddr *src_addr, socklen_t *addrlen);

参数:

  • int sockfd:指定要从哪个文件描述符中获取数据,填accept函数获取到的新的文件描述符;
  • void *buf:该指针指向的内存空间中存储获取到的数据,可以是任意类型数据;
  • size_t len:指定要接收的数据大小,以字节为单位;
    • int flags:
      0:阻塞方式接收,当没有数据的时候阻塞;
      MSG _DONTWAIT:非阻塞;
  • struct sockaddr *src_addr:通用地址信息结构体,该地址信息结构体中存储数据包是从谁那里发送过来的。
    如果不想知道从谁那里过来,则填NULL;
  • socklen_t *addrlen:真实的地址信息结构体的大小,注意是指针类型,需要在外部定义普通变量,赋值后取地址;
    如果上一个参数填NULL,则当前参数填NULL;

返回值:

  • >0 , 成功,返回成功接收到的字节数;
  • =0, 对端关闭,返回0; 只适用于TCP情况;
  • =-1, 函数运行失败,更新errno;

recv(sockfd, buf, len, flags); 相当于 recvfrom(sockfd, buf, len, flags, NULL, NULL);

2.4 sendto(发送数据)

功能:将数据发送到指定的套接字中,需要指定发给谁,即指定好接收方的地址信息结构体
原型:

#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
          const struct sockaddr *dest_addr, socklen_t addrlen);

参数:

  • int sockfd:指定要向哪个文件描述符发送数据,填accept函数获取到的新的文件描述符;

  • void *buf:指定要发送的数据首地址,可以是任意类型数据;

  • size_t len:指定要发送的数据大小,以字节为单位;

  • int flags:

    • 0:阻塞方式发送,当数据满的时候阻塞;
    • MSG_DONTWAIT:非阻塞;
  • const struct sockaddr *dest_addr:通用地址信息结构体,真实的地址信息结构体跟着地址族来定
    需要填充接收方的地址信息结构体,指定数据要发给谁;

  • socklen_t addrlen:真实的地址信息结构体的大小:sizeof(struct sockaddr_in);

返回值:

  • 成功,返回成功发送的字节数;
  • 失败,返回-1,更新errno;

send(sockfd, buf, len, flags); 相当于sendto(sockfd, buf, len, flags, NULL, 0);

3. UDP中的connect函数(重点!)

  1. udp中可以使用connect函数,但是不会产生连接

    ​ TCP中的connect函数会产生三次握手,将client和server连接。

    ​ UDP中的connect函数,仅仅是将对端的IP和端口记录到内核套接字空间中,此时是udp只能与记录的对端进行通信。

  2. TCP中的connect函数只能被调用一次。

    UDP中的connect函数可以被调用多次,刷新内核中对端的IP和端口,

    如果想要清空内核中对端的地址信息,则将sin_family

    成员设置为AF_UNSPEC,调用connect函数即可。

  3. 当udp采用connect函数的方式收发报文后,可以调用send write recv read函数。也可以使用sendto recvfrom.但是需要使用以下形式

    sendto(sfd, buf, sizeof(buf), 0, NULL, 0);
    recvfrom(sfd, buf, sizeof(buf), 0, NULL, NULL);
    

udp中的connect函数的优点:

  1. 提升传输效率

    1. 不调用connect: 将对端的信息填充到内核 —> 发送报文 —>清空内核信息 —>将对端的信息填充到内核 —> 发送报文 —>清空内核信息—>…
    2. 调用connect: 将对端的信息填充到内核 —> 发送报文 —> 发送报文 —> 发送报文—> 发送报文
  2. 增加传输时候的稳定性

    sendto(sfd, buf, sizeof(buf), 0, NULL, 0);
    recvfrom(sfd, buf, sizeof(buf), 0, NULL, NULL);
    

udp中的connect函数的优点:

  1. 提升传输效率

    1. 不调用connect: 将对端的信息填充到内核 —> 发送报文 —>清空内核信息 —>将对端的信息填充到内核 —> 发送报文 —>清空内核信息—>…
    2. 调用connect: 将对端的信息填充到内核 —> 发送报文 —> 发送报文 —> 发送报文—> 发送报文
  2. 增加传输时候的稳定性

    1. 可以防止AB进程在做大量数据传输过程中,接收到C进程的数据,造成数据错误。

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

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

相关文章

云日记个人中心项目思路

验证昵称的唯一性 前台&#xff1a; 昵称文本框的失焦事件 blur 1. 获取昵称文本框的值 2. 判断值是否为空 如果为空&#xff0c;提示用户&#xff0c;禁用按钮&#xff0c;并return 3. 判断昵称是否做了修改…

一文详解:linux部署jenkins,一键构建并部署springboot至第三方服务器

目录 1、下载jenkins 2、 启动jenkins 3、访问jenkins 4、在当前Linux上安装maven 4.1、更新wget命令&#xff0c;支持https请求 4.2、下载maven 4.3、解压安装maven 4.4、配置maven环境变量 4.5、maven配置阿里云镜像 4.6、配置maven依赖下载的位置 5、Linux安装Gi…

Redis的使用【Redis】

一、缓存简介 缓存简介 二、缓存分类 缓存分类 三、常见缓存 常见缓存 四、Redis使用 Redis 有 5 ⼤基础数据类型&#xff1a; String——字符串类型Hash——字典类型List——列表类型Set——集合类型ZSet——有序集合类型 其中最常⽤的是字符串和字典类型。 1.字符…

Vulnhub靶场DC-1练习

目录0x00 准备0x01 主机信息收集0x02 站点信息收集0x03 漏洞查找与利用0x00 准备 下载链接&#xff1a;https://download.vulnhub.com/dc/DC-1.zip 介绍&#xff1a;There are five flags in total, but the ultimate goal is to find and read the flag in root’s home dir…

常见的DNS攻击与防御

DNS查询通常都是基于UDP的&#xff0c;这就导致了在查询过程中验证机制的缺失&#xff0c;黑客很容易利用该漏洞进行分析。DNS服务可能面临如下DNS攻击风险&#xff1a; 黑客伪造客户端源IP地址发送大量的DNS请求报文&#xff0c;造成DNS request flood攻击。黑客伪造成授权服…

Node.js安装与配置步骤

前言一、安装Node.js1.下载2.安装3.添加环境变量二、验证是否安装成功三、修改模块下载位置1.查看npm默认存放位置2.在 nodejs 安装目录下&#xff0c;创建 “node_global” 和 “node_cache” 两个文件夹3.修改默认文件夹4.测试默认位置是否更改成功四、设置淘宝镜像1.将npm默…

ARM Linux 内核启动2 ——C语言阶段

一、内核启动的C语言阶段 1 1、这一块的学习思路 (1) 抓大放小&#xff0c;不深究。 (2) 感兴趣可以就某个话题去网上搜索资料学习。 (3) 重点局部深入分析。 2、具体学习方法 (1) 顺着代码执行路径抓全。这是我们的学习主线。 (2) 对照内核启动的打印信息进行分析。 3、…

Ansible批量部署采集器

千台服务器部署采集器的时候用到了 Ansible&#xff0c;简单记录一下。 安装 Ansible pip install ansible yum install ansible –y在 /etc/ansible/hosts 中添加被管理组 &#xff0c;比如图中[web] 是组的名字。 执行ansible命令测试&#xff0c;通过hosts中定义的web组执…

君子签「数据签」正式上线,推动企业电子合同实现高效安全签署

近年来&#xff0c;从政府机关到企事业单位&#xff0c;数字化转型步伐明显加快。 在数字化的驱动下&#xff0c;在各行业的服务过程中&#xff0c;君子签对产品部署有了更深的沉淀和经验&#xff0c;通过不断打磨、升级产品&#xff0c;「数据签」产品于近日正式上线&#xf…

Word这样用,提高效率不加班

Word这样用&#xff0c;提高效率不加班 今天给大家分享23条Word文档的应用小技巧。对于大家来说&#xff0c;掌握些技巧能够效率百倍&#xff0c;何乐不为&#xff1f; 这些技巧是本人通过整理一直在用并且使用频率较高的&#xff0c;也希望能帮到大家。有兴趣的小伙伴可以自己…

Python | 基于LendingClub数据的分类预测研究Part01——问题重述+特征选择+算法对比

欢迎交流学习~~ 专栏&#xff1a; 机器学习&深度学习 本文利用Python对数据集进行数据分析&#xff0c;并用多种机器学习算法进行分类预测。 具体文章和数据集可以见我所发布的资源&#xff1a;发布的资源 Python | 基于LendingClub数据的分类预测研究Part01——问题重述特…

多路I/O转接 Epoll

基本概述 epoll是Linux下多路复用IO接口select/poll的增强版本&#xff0c;它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率&#xff0c;因为它会复用文件描述符集合来传递结果而不用迫使开发者每次等待事件之前都必须重新准备要被监听的文件描述符集合…

从输入url到页面展现(二)找服务器其实是在找IP地址

前言 前一节我们讲述了url的规则&#xff0c;url的几种类型&#xff0c;以及访问web服务器的时候&#xff0c;如果用户访问的url如果不包含index.html的话&#xff0c;大概会如何去寻找这个url对应的文件&#xff0c;如果感兴趣的同学可以回头去看上一篇&#xff1a;从输入url…

PyTorch中的可视化工具

目录 一、网络结构的可视化 1.1 通过HiddenLayer可视化网络 1.2 通过PyTorchViz可视化网络 二、训练过程可视化 2.1 通过tensorboardX可视化训练过程 2.2 HiddenLayer可视化训练过程 三、使用Visdom进行可视化 一、网络结构的可视化 我们训练神经网络时&#xff0c;除…

xshell是什么软件

xshell是什么软件? Xshell 是一个强大的远程管理软件&#xff0c;它支持SSH&#xff0c;TELNET 协议。Xshell可以在Windows下访问远端服务器、路由器、网络机顶盒等&#xff0c;类似的常用软件还有putty&#xff0c;以及Windows下的Telnet。 下面简单介绍一下xshell软件。 X…

康耐视Designer,通过VC5与三菱Q系列PLC-SLMP通讯说明

测试使用软件版本 Designer Version: 2.7 GX Works2 Version: 1.77F 测试使用硬件 Cognex Vision Controller VC5 CIC-5000R Mitsubishi PLC: Q06UDEHCPU PLC端设置(内置以太网口型号) 1.新建一个工程,选择对应的PLC系列和PLC类型: 2.PLC参数设置(以太网设置):…

LabVIEW-数值控件和布尔控件

简介 LabVIEW 以其强大、开放、图形化的虚拟仪器软件开发环境使得无论是否有过编程经验的工程师或科学家使用它时都可以快速、高效地与测量和控制硬件通信&#xff0c;并进行复杂的数据分析及处理。LabVIEW集成了满足GPIB、PXI、VXI、RS232、RS485、USB、DAQ等多种形式的设备互…

MATLAB算法实战应用案例精讲-【自动驾驶】激光雷达LiDAR(补充篇)

目录 前言 几个高频面试题目 自动驾驶中的传感器&#xff1a;LiDAR和 Radar的区别 LiDAR Radar 性能对比 激光雷达中是如何做到和GPS时间同步的&#xff1f; 一、三种方案PPSGPRMC、PTP、gPTP 二、同步过程 算法原理 发展历程 国内外厂商 算法思想 测距 三角测…

【博学谷学习记录】超强总结,用心分享丨人工智能 AI项目 前向概率计算笔记

目录前向概率模型基础参数公式推导代码实现前向概率 给定隐马尔可夫模型λ\lambdaλ&#xff0c;定义到时刻ttt部分观测序列为o1,o2,⋯,oto_1,o_2,\cdots,o_to1​,o2​,⋯,ot​且状态为sis_isi​的概率为前向概率&#xff0c;记作αt(i)P(o1,o2,⋯,ot,itsi∣λ)\alpha_t(i)P(o…

GDPU C语言 天码行空9

填空题 1. 指针排序 数组 输入 n5 30 85 12 77 6输出 6 12 30 77 85 &#x1f920; 代码 #include<stdio.h>#define N 10void sort(int *x,int n)// *x 是 数组 a 的地址 {int i,j,k,t;for(i0;i<n-1;i)//从前往后枚举 坑位{ki; for(ji1;j<n;j) if(x[k…