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 
 
int socket(int domain, int type, int protocol);
功能:
创建一个用来通信的文件描述符
参数:
domain:使用的协议族 AF_INET (IPv4协议族)
type:套接字类型
SOCK_STREAM:流式套接字
SOCK_DGRAM:数据报套接字
SOCK_RAW:原始套接字
protocol:协议
默认为0
返回值:
成功返回文件描述符
失败返回-1
sendto
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
功能:
利用套接字向指定地址发送数据信息
参数:
sockfd:套接字文件描述符
buf:发送数据空间首地址
len:发送数据的长度
flags:属性默认为0
dest_addr:目的地址信息存放的空间首地址
addrlen:目的地址的长度
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 */
};/* Internet address. */
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
返回值:
成功返回实际发送字节数
失败返回-1
inet_addr
in_addr_t inet_addr(const char *cp);
功能:
将字符串IP地址转换为内存中的IP地址
htons
uint16_t htons(uint16_t hostshort);
功能:
将本地字节序转换为网络的大端字节序
close(sockfd) 关闭套接字
2.收端
bind
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能:
在套接字上绑定一个IP地址和端口号
参数:
sockfd:套接字文件描述符
addr:绑定IP地址空间首地址
addrlen:绑定IP地址的长度
返回值:
成功返回0
失败返回-1
recvfrom
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
功能:
从套接字中接收数据
参数:
sockfd:套接字文件描述符
buf:存放数据空间首地址
flags:属性 默认为0
src_addr:存放IP地址信息的空间首地址
addrlen:存放接收到IP地址大小空间的首地址
返回值:
成功返回实际接收字节数
失败返回-1
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
#endifsend.c
/*************************************************************************> 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); //设置接收方的端口号为50000recvaddr.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;}recv.c
/*************************************************************************> 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;
}makefile (使用make 一键编译)
all:send recv send:send.c gcc $^ -o $@
recv:recv.c gcc $^ -o $@.PHONY:
clean:rm send recv