当前位置: 首页 > ops >正文

网络编程——TCP、UDP

1.基础知识

1.概念

不同主机的进程间通信

2.基本通信流程

ip地址 ---就是网络中身份证 ---- 用来唯一的标识一台主机

 ip = 网络号 + 主机号 

ip 本质 32位的数值 

点分十进制 

子网掩码

255.255.255.0

用来区分网络

默认网关

用于发送ip

DNS

将域名转化为用于寻址的ip地址

3.分层

osi模型 (开放的系统互联模型) 
7.应用层 //  
6.表示层 //加密传输的需要  --- 数据的格式化 
加密解密  gzip


5.会话层 //连接状态 --长连接 ,短链接,连接的质量问题 
网络断开,连接状态,keep-close keep-alive
//登录某个网站:

4.传输层 //传输控制协议 
tcp  udp  协议  文件    视频,音频
可靠传输 & 
tcp: 
下载文件,传输文件。
udp:
音频,视频,游戏开黑

3.网络层         ----- 数据包 (packet)
ip   NAT   
//怎么找到 对方

 

        2.链路层   (封装成帧 + 差错控制)      
交换机   (全双工,实时的工作的。)
数据的格式化  (大量数据交互时,字节为单位,字节大小端)
帧      
校验

1.物理层      ----- bit流    
100Mb/8  Gbits   100MB 同轴电缆
(
电气特性: 0,1高低电平特性
物理特性: 0,1

              规程特性: 超5类 ,超6类,远距离传输

2.tcp编程函数接口

1.socket 

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
功能:
创建了通信的一端 
返回文件描述符 
参数:
@domain    //域 -- 范围 
//ip地址 
// ipv4  32位数据 
// ipv6  128位 
//本地套接字 
//protocol //协议
AF_INET
@type       //用来说明socket这种网络通信的文件的类型 
SOCK_STREAM   //流式套接字 ---tcp 
SOCK_DGRAM     //数据报套接字 ---udp
@protocol   //协议 
0    //linux系统上 SOCK_STREAM --- TCP
//类linux系统行 
//          SOCK_DGRAM --- UDP
返回值:
成功  返回socket对应的fd
失败  -1 && errno被设置  //perror 

注:两个重点协议

TCP(transmision control protocol):(类似 打电话)---可靠(1.连接 2.可靠传输 3.字节流)
1.特点:
a.面向连接(就是在进行通信之前,必须建立好一条逻辑上的通路)
b.提供可靠传输(四个"无",无丢失,无失序,无差错,无重复)

2.建立连接: 
tcp三次握手 目的:建立连接

        client      ------------------  server
1           -- 我要通话     -->  1   //连接的请求 
2           <--嗯,我知道了,你可以-- //对方接听电话 喂 
3            -- 嗯,好的     -->     //喂

3.应用场合:
(1). 对可靠性要求较高场合
(2). QQ微信等 软件的登录

UDP(User datagram Protocol):(类似 生活中的广播) (1.不可靠, 2.无连接 3.数据报)
1.特点:
不提供可靠传输,
在数据发送时,不需要建立连接

2.应用:
(1).小数据,但是对速度要求较高
(QQ.及时文本信息,语音等),实时性要求较高场合!
(2).广播,组播   //电子教师(vnc --- 广播)
(3).无线网的传输 //udp 

2.connect

int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能:
通过socket链接到指定的地址上 
参数:
@sockfd  --- socket创建的fd
@addr    --- 标识网络中一个进程对应的地址 
ip      确定一台主机 
端口号   用来标识一个网络通信的进程 
ip+端口号 
struct sockaddr *addr//不是通用的 
socket 不同的通信范围 
不同通信域 都有自己特定的结构体 
ipv4
struct sockaddr_in {
sa_family_t    sin_family; /* address family: AF_INET */
in_port_t      sin_port;   /* port in network byte order */
struct in_addr sin_addr;   /* internet address -- ip地址*/
};                                                                                                                                                          /* Internet address. */
struct in_addr {
in_addr_t      s_addr;     /* address in network byte order */
};
in_addr_t inet_addr(const char *cp);
@addrlen  
说明 第二个参数的 地址类型的大小 
返回值:
成功 0
失败 -1&&errno                                                                                                                       

端口号:
16位的整型数据 

  0~1023 //1024 ---知名端口号 
//http -- 80 
1024~50000  //特定端口号 
50000~  //临时分配的端口号 

大小端 
发送 --- 转换 --- 网络字节序 (大端)
接收 --- 根据主机的大小端转换 
#include <arpa/inet.h>

uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

h -- host
to -- 到 
n --network 

l -- long   //处理4字节数据 
s -- short  //处理2字节数据 


in_addr_t inet_addr(const char *cp);
cp 表示要用的ip地址的字符串 //点分十进制 
"192.168.0.150"
返回:
网络字节序形式的ip地址的32位数值 

    

3.bind

int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
int bind   (int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:
给sockfd 绑定一个地址信息(ip+port)
参数:
@sockfd  --- 要操作的socket 
@addr    --- 要绑定的地址信息 
@addrlen --- 地址信息对应的大小 
返回值:
成功 0
失败 -1&&errno

4.listen

 int listen(int sockfd, int backlog);
功能:
将sockfd对应的socket设置为监听套接字 
//这个套接字 负责看 有没有客户端,发送连接请求 
//有了放等待队列中
参数:
@sockfd  ---socket 的fd
@backlog  --- 等待队列的长度 
返回值:
成功 0
失败 -1&&errno
//dos 攻击 

5.accept 

int accept (int sockfd,     struct sockaddr *addr, socklen_t *addrlen);
功能:
从监听的socket中提取连接请求,完成连接(三次握手)
返回已连接的一个新socket 
参数:
@sockfd --- 监听的socket的fd
@addr   --- 用来存放,客户端的地址信息 
@addrlen --- 值结果参数 
注意:  必须初始化 ,初始成 addr对应sockaddr_in 类型的大小               
返回值:
成功 返回 已连接的socket的fd  //专门用于后面通信的 
失败 -1 &&errno 

6.send

 ssize_t read(    int fd, void *buf, size_t count );

      recv(sockfd,buf,sizeof(buf),0);<=>read(sockfd,buf,sizeof(buf),0);

ssize_t send(int sockfd, const void *buf, size_t len  , int flags);
功能:
向socket中发送信息 
参数:
@sockfd --- 要操作的socket
@buf    --- 存放数据的空间 
@len    --- 发送的数据大小 
@flags  --- 操作标志
MSG_DONTWAIT
返回值:
成功 发送出去字节数 
失败 -1 && errno 

7.recv

  ssize_t recv(int sockfd, void *buf, size_t len  , int flags);
功能:
从socket中接收信息 
参数:
@sockfd --- 要操作的socket
@buf    --- 存放数据的空间 
@len    --- buf的大小 
@flags  --- 指定读取信息的操作标志
MSG_DONTWAIT
返回值:
成功 读取到的字节数 
失败 -1 && errno 

 3.udp编程函数接口

1.socket
2.sendto

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

 功能:
向socket中发送信息 
参数:
@sockfd --- 要操作的socket
@buf    --- 存放数据的空间 
@len    --- 发送的数据大小 
@flags  --- 操作标志
MSG_DONTWAIT
@dest_addr  --- 要发送到的目的地址 
@addrlen    --- 地址大小
返回值:
成功 发送出去字节数 
失败 -1 && errno 

3.bind
4.recvfrom

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
功能:
从socket中接收信息 
参数:
@sockfd --- 要操作的socket
@buf    --- 存放数据的空间 
@len    --- buf的大小 
@flags  --- 指定读取信息的操作标志
MSG_DONTWAIT
@src_addr --- 保存 客户端的地址信息 
@addrlen  --- 值结果参数 
注意: 
使用时,需要 初始化 addrlen = sizeof(struct sockaddr_in);
返回值:
成功 读取到的字节数 
失败 -1 && errno 

4.交互过程

1.tcp

客户端 

  • socket
  • connect
  • recv/send
  • close

服务器端

  • socket 
  • bind
  • listen
  • accept 
  • recv/send
  • close

:交互过程中可能会出现粘包现象,是因为tcp的交互的特殊性导致的

       解决方式:要让消息之间有边界 

        a. 结束标志 \r\n 
    b. 固定长度 
    c. 协议结构体 

    2.udp

    客户端:主动 

    • socket
    • sendto 
    • recvfrom 
    • close

    服务器端:被动 

    • socket
    • bind
    • recvfrom
    • printf
    • sendto
    • close 

    http://www.xdnf.cn/news/18718.html

    相关文章:

  • ADC-工业信号采集卡-K004规格书
  • JWT用户认证后微服务间如何认证?(双向TLS(mTLS)、API网关、Refresh Token刷新Token)微服务间不传递用户认证Token
  • zookeeper基础概念及部署
  • Redis缓存雪崩缓存击穿缓存穿透的处理方式
  • java18学习笔记
  • Nuxt.js@4 中管理 HTML <head> 标签
  • AI 伦理的 “灰色地带”:数据隐私与技术创新如何平衡?
  • 零知开源——基于STM32F103RBT6和ADXL335实现SG90舵机姿态控制系统
  • Coze用户账号设置修改用户头像-前端源码
  • 深度学习之第三课PyTorch( MNIST 手写数字识别神经网络模型)
  • AI创业公司:Freya 金融语音AI Agent
  • 电池分选机:破解电池性能一致性难题的自动化方案|深圳比斯特
  • 【VS2022】背景设置详细教程(背景透明)
  • 智数园区-前台
  • Linux的奇妙冒险———进程信号
  • 算法每日一题 | 入门-分支结构-肥胖问题
  • java 并发编程八股-多线程篇
  • 【iOS】内存管理及部分Runtime复习
  • Kubernetes高可用架构设计:多Master节点部署与etcd集群运维深度指南
  • centos7 安装coze
  • ZYNQ [Petalinux的运行]
  • Pytorch框架的训练测试以及优化
  • 数据结构青铜到王者第三话---ArrayList与顺序表(2)
  • 区块链技术原理(18)-以太坊共识机制
  • 哈夫曼树详解
  • 神经网络|(十五)概率论基础知识-协方差标准化和皮尔逊相关系数
  • 人机协作,温暖升级:有鹿机器人与保洁张阿姨的故事
  • 2025年06月 Python(二级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • Python Day 33 JavaScript BOM 与 DOM 核心笔记整合
  • Linux(从入门到精通)