网络编程——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
相关推荐
励志五个月成为嵌入式糕手22 分钟前
0825 http梳理作业
网络·网络协议·http
dxt_snow2 小时前
docker在自定义网络中安装ElasticSearch和Kibana
网络·elasticsearch·docker
左灯右行的爱情2 小时前
分库分表系列-基础内容
网络·数据库·oracle
DebugKitty2 小时前
网络编程1-基本概念、函数接口
运维·服务器·网络·网络协议·socket·tcp
2501_921290443 小时前
嵌入式第三十六天(网络编程(TCP))
网络·网络协议·tcp/ip
YC运维4 小时前
Linux服务测试题(DNS,NFS,DHCP,HTTP)
linux·网络
刘 大 望5 小时前
网络编程--TCP/UDP Socket套接字
java·运维·服务器·网络·数据结构·java-ee·intellij-idea
青草地溪水旁5 小时前
HTTP数据之旅:一个网络请求的完整冒险
网络·网络协议·http
小白iP代理6 小时前
国内代理 IP 的类型:住宅 IP、机房 IP、移动 4G/5G IP 区别
网络·tcp/ip·5g