1.网络协议模型:
OSI协议模型
应用层 实际发送的数据
表示层 发送的数据是否加密
会话层 是否建立会话连接
传输层 数据传输的方式(数据报、流式)
网络层 数据的路由(如何从一个局域网到达另一个局域网) IP地址
数据链路层 局域网下如何通信
物理层 物理介质的连接
TCP/IP协议模型
应用层 传输的数据
传输层 传输的方式
网络层 数据如何从一台主机到达另一台主机
网络接口层 物理介质的连接
应用层:
HTTP 超文本传输协议
HTTPS
FTP 文件传输协议
TFTP 简单文本传输协议
SMTP 邮件传输协议
MQTT
TELNET
..
传输层:
UDP 用户数据报协议
特点:
1.实现机制简单
2.资源开销小
3.不安全不可靠
TCP 传输控制协议
特点:
1.实现机制复杂
2.资源开销大
3.安全可靠
网络层:
IPv4
IP地址:唯一标识网络中一台主机的标号
IP地址:网络位 + 主机位
子网掩码:用来标识IP地址的网络位和主机位
子网掩码是1的部分表示IP地址的网络位
子网掩码是0的部分表示IP地址的主机位
网段号:网络位不变,主机位全为0,表示网段号
广播地址:网络位不变,主机位全为1,表示广播地址
IP地址类型:
A类
1.0.0.0 - 126.255.255.255
子网掩码:255.0.0.0
管理超大规模网络
10.0.0.0 - 10.255.255.255
B类
128.0.0.0 - 191.255.255.255
子网掩码:255.255.0.0
管理大中规模型网络
172.16.0.0 - 172.31.255.255
C类
192.0.0.0 - 223.255.255.255
子网掩码:255.255.255.0
管理中小规模型网络
192.168.0.0 - 192.168.255.255
D类
224.0.0.0 - 239.0.0.0
用于组播
E类
240.0.0.0 - 255.255.255.255
用于实验
UDP编程
socket套接字编程:
发端:socket -> sendto -> close
收端: socket -> bind -> recvfrom -> close
1.发端:
socket
sendto
inet_addr
htons
close(sockfd) 关闭套接字
2.收端
bind
recvfrom
UDP 基础的发送与接收的例程
head.h
#ifndef _HEAD_H
#define _HEAD_H
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/wait.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<grp.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/shm.h>
#include<sys/sem.h>
#include<sys/socket.h>
#include<netinet/ip.h>
#include<arpa/inet.h>
#define RECV_ADDR "192.168.1.157"
#define RECV_PORT 50000
#endif
/*************************************************************************
> File Name: send.c
> Author: yas
> Mail: rage_yas@hotmail.com
> Created Time: 2024年03月06日 星期三 22时06分24秒
************************************************************************/
#include"head.h"
int main(void)
{
int sockfd = 0; //创建整型sockfd 用来保存socket(套件字)文件描述符
char tmpbuff[1024] = {0}; // 发送的数据
ssize_t nsize = 0; //发送数据的大小
struct sockaddr_in recvaddr; //创建sockaddr_in类型的结构体 recvaddr 用于保存 接收方 的地址信息
sockfd = socket(AF_INET,SOCK_DGRAM,0);// AF_INET 表示IPv4 协议 SOCK_DGRAM 表示数据报套接字
if(-1 == sockfd)
{
perror("fail to socket");
return -1;
}
recvaddr.sin_family = AF_INET; //设置接收方地址的地址族 为AF_INET (IPv4)
recvaddr.sin_port = htons(50000); //设置接收方的端口号为50000
recvaddr.sin_addr.s_addr = inet_addr("192.168.1.157"); //设置接收方的IP地址为“192.168.1.157”
//inet_addr 将ip地址转换为网络字节序
gets(tmpbuff);
nsize = sendto(sockfd,tmpbuff,strlen(tmpbuff),0,(struct sockaddr *)&recvaddr,sizeof(recvaddr));//sendto将 tmpbuff 中的数据发送给接收方
//参数依次是 套接字文件描述符、待发送数据的首地址、发送数据的大小、接收方地址信息的指针、接收方地址信息的大小
if(-1 == nsize)
{
perror("fail to sendto");
return -1;
}
close(sockfd);
return 0;
}
/*************************************************************************
> File Name: recv.c
> Author: yas
> Mail: rage_yas@hotmail.com
> Created Time: 2024年03月06日 星期三 22时21分52秒
************************************************************************/
#include"head.h"
int main(void)
{
int ret = 0;
int sockfd = 0;
struct sockaddr_in recvaddr;
struct sockaddr_in sendaddr;
socklen_t addrlen = sizeof(sendaddr);
char tmpbuff[1024] = {0};
ssize_t nsize = 0;
sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(-1 == sockfd)
{
perror("fail to socket");
return -1;
}
recvaddr.sin_family = AF_INET;
recvaddr.sin_port = htons(50000);
recvaddr.sin_addr.s_addr = inet_addr("192.168.1.157");
//设置接收方地址的信息,使用bind 将套接字与接收方的地址绑定
ret = bind(sockfd,(struct sockaddr *)&recvaddr,sizeof(recvaddr));//bind 参数依次为 套接字文件描述符、指向待绑定地址信息的指针、地址信息的大小
if(-1 == ret)
{
perror("fail to bind");
return -1;
}
nsize = recvfrom(sockfd,tmpbuff,sizeof(tmpbuff),0,(struct sockaddr *)&sendaddr,&addrlen);
//从套接字接收数据并保存在tmpbuff中
//recvfrom参数依次为 套接字文件描述符、接收数据的缓冲区、缓冲区大小、标志位、指向发送方地址信息的指针、地址信息的长度
if(-1 == nsize)
{
perror("fail to recvfrom");
return -1;
}
printf("RECV FROM %s:%d>%s\n",inet_ntoa(sendaddr.sin_addr),ntohs(sendaddr.sin_port),tmpbuff);
// 返回发送端的ip地址和端口号
close(sockfd);
return 0;
}
all:send recv
send:send.c
gcc $^ -o $@
recv:recv.c
gcc $^ -o $@
.PHONY:
clean:
rm send recv