网络、网络协议模型、UDP编程——计算机网络——day01

news2025/1/24 17:52:48

今天来到了网络编程,主要讲了网络、网络协议模型以及UDP编程

网络

网络主要是进行:数据传输和数据共享

网络协议模型

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套接字编程

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 
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 
inet_addr、htons
inet_addr:
	in_addr_t inet_addr(const char *cp);
	功能:  
	    将字符串IP地址转换为内存中的IP地址 

htons
	uint16_t htons(uint16_t hostshort);
	功能:
	    将本地字节序转换为网络的大端字节序

eg:编写程序实现从终端接收字符串发送给 windows软件调试助手,并接受软件助手的回复,显示在终端屏幕上

#include"head.h"

int main(void)
{
	int sockfd = 0;
	struct sockaddr_in recvaddr;	
	struct sockaddr_in addc;
	char tmpbuff[1024] = {"hello world"};	//发送的字符串
	char recvbuff[1024] = {0};
	ssize_t nsize = 0;
	socklen_t addrlen;

	sockfd = socket(AF_INET,SOCK_DGRAM,0);	//参数1:IPv4协议族;参数2:数据报套接字;参数3:协议,默认为0
	if(-1 == sockfd)
	{
		perror("fail to socket");
		return -1;
	}
	
	
	recvaddr.sin_family = AF_INET;
	recvaddr.sin_port = htons(50000);	//将端口50000转为网络的大端模式
	recvaddr.sin_addr.s_addr = inet_addr("192.168.1.104");//将字符串IP地址转为内存中的IP地址
	addrlen = sizeof(addc);
	nsize = sendto(sockfd,tmpbuff,strlen(tmpbuff),0,(struct sockaddr *)&recvaddr,sizeof(recvaddr));
	if(-1 == nsize)
	{
		perror("fail to sendto");
		return -1;
	}

	printf("成功发送 %ld 字节!\n",nsize);

	recvfrom(sockfd,recvbuff,sizeof(recvbuff),0,(struct sockaddr *)&addc,&addrlen);	//接收
	printf("%s",recvbuff);

	close(sockfd);

	return 0;
}

结果:
在这里插入图片描述

我们可以看到

发端:socket -> sendto -> close

收端: socket -> bind -> recvfrom -> close

UDP需要注意的细节点

1.UDP是无连接,发端退出,收端没有任何影响
2.UDP发送数据上限,最好不要超过1500个字节
3.UDP是不安全不可靠的,连续且快速的传输数据容易产生数据丢失

UDP包头长度:8个字节

 分别是:源端口号(2个字节)
		 目的端口号(2个字节)
	     长度(2个字节)
		 校验和(2个字节)

eg:要求在不同主机中编写两个程序,实现全双工聊天功能
1.进入软件后接收当前用户的昵称
2.显示的格式为 对方用户昵称(对方IP:对方端口)>接收到的内容
3.用户输入".quit"退出聊天
4.网络通信时收发结构体
struct person
{
char name[32];
char text[512];
};

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 <dirent.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/in.h>

struct person
{
	char name[32];
	char text[512];
};

#endif

client.c

#include"head.h"

int sockfd = 0;
struct sockaddr_in sendaddr;
struct sockaddr_in recvaddr;
ssize_t nsize = 0;
socklen_t addrlen = sizeof(recvaddr);

void *threadSend(void *arg)	//发端
{
	struct person user;
		
	scanf("%s",user.name);
	nsize = sendto(sockfd,user.name,strlen(user.name),0,(struct sockaddr *)&sendaddr,sizeof(sendaddr));
	if(-1 == nsize)
	{
		perror("fail to sendto");
		return NULL;
	}
	while(1)
	{
		memset(&user.text,0,sizeof(user.text));
		scanf("%s",user.text);
		nsize = sendto(sockfd,user.text,strlen(user.text),0,(struct sockaddr *)&sendaddr,sizeof(sendaddr));
		if(-1 == nsize)
		{
			perror("fail to sendto");
			return NULL;
		}

		if(!strcmp(user.text,".quit"))
		{
			break;
		}
	}
}

void *threadRecv(void *arg)
{
	struct person user;
	
	nsize = recvfrom(sockfd,user.name,sizeof(user.name),0,(struct sockaddr *)&recvaddr,&addrlen);		//首先接收名字
	if(-1 == nsize)
	{
		perror("fail to recvfrom");
		return NULL;
	}

	while(1)
	{
		memset(&user.text,0,sizeof(user.text));		//刷新
		nsize = recvfrom(sockfd,user.text,sizeof(user.text),0,(struct sockaddr *)&recvaddr,&addrlen);
		if(-1 == nsize)
		{
			perror("fail to recvfrom");
			return NULL;
		}

		if(!strcmp(user.text,".quit"))
		{
			break;
		}
		printf("%s %s:%d > %s\n",user.name,inet_ntoa(recvaddr.sin_addr),ntohs(recvaddr.sin_port),user.text);
	}
}

int main(void)
{
	int ret = 0;

	pthread_t send;
	pthread_t recv;

	pthread_create(&send,NULL,threadSend,NULL);		//创建发送线程
	pthread_create(&recv,NULL,threadRecv,NULL);		//创建接收线程

	sockfd = socket(AF_INET,SOCK_DGRAM,0);	
	if(-1 == sockfd)
	{
		perror("fail to socket");
		return -1;
	}

	sendaddr.sin_family = AF_INET;
	sendaddr.sin_port = htons(50000);
	sendaddr.sin_addr.s_addr = inet_addr("192.168.1.174");

	recvaddr.sin_family = AF_INET;
	recvaddr.sin_port = htons(50000);
	recvaddr.sin_addr.s_addr = inet_addr("192.168.1.152");
	ret = bind(sockfd,(struct sockaddr *)&recvaddr,sizeof(recvaddr));	//绑定接收端的IP地址和端口号
	if(-1 == ret)
	{
		perror("fail to bind");
		return -1;
	}

	pthread_join(send,NULL);
	pthread_join(recv,NULL);

	close(sockfd);

	return 0;
}

结果:
在这里插入图片描述

以上就是今天内容!

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

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

相关文章

激光炸弹c++

题目 输入样例&#xff1a; 2 1 0 0 1 1 1 1输出样例&#xff1a; 1 思路 由题知本题要求某个区间内数的和&#xff0c;联想到二维前缀和。我们可以先使用二维前缀和模板计算各区间的价值。然后枚举以某点为右下角&#xff0c;大小为R*R的正方形价值&#xff0c;取最大值。 …

06 - 镜像管理之:基础知识

1 了解镜像 Docker镜像是一个特殊的文件系统&#xff0c;除了提供容器运行时所需的程序、库、资源、配置等文件外&#xff0c;还包含了一些为运行时准备的一些配置参数&#xff08;如匿名卷、环境变量、用户等&#xff09;。 但注意&#xff0c; 镜像不包含任何动态数据&#…

【DataRoom】- 基于VUE的开源的大屏可视化设计器

【DataRoom】- 基于VUE的开源的大屏可视化设计器 DataRoom是一款基于SpringBoot、MyBatisPlus、Vue、ElementUI、G2Plot、Echarts等技术栈的大屏设计器&#xff0c;具备大屏设计、预览能力&#xff0c;支持MySQL、Oracle、PostgreSQL、SQLServer、ElasticSearch、JSON、JS、HTT…

springcloud:3.7测试线程池服务隔离

服务提供者【test-provider8001】 Openfeign远程调用服务提供者搭建 文章地址http://t.csdnimg.cn/06iz8 相关接口 测试远程调用&#xff1a;http://localhost:8001/payment/index 服务消费者【test-consumer-resilience4j8004】 Openfeign远程调用消费者搭建 文章地址http://t…

Dubbo的线程模型

1 线程模型概述 Dubbo默认的底层网络通信使用的是Netty。 服务提供方NettyServer使用两级线程池&#xff0c;其EventLoopGroup&#xff08;boss&#xff09;主要用来接收客户端的连接请求&#xff0c;并把完成TCP三次握手的连接分发给EventLoopGroup&#xff08;worker&#…

【音视频开发好书推荐】RTC程序设计:实时音视频权威指南

目录 1、WebRTC概述2、好书推荐3、本书内容4、本书特色5、作者简介6、谁适合看这本书 1、WebRTC概述 WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个由Google发起的实时音视频通讯C开源库&#xff0c;其提供了音视频采集、编码、网络传输&#xff0c;解码显…

【考研数学】基础660太难了?一个办法搞定660

觉得题目太难&#xff0c;大概率是题目超出了自己当前的水平 题型没见过&#xff0c;或者太复杂&#xff0c;属于跳级学习了&#xff0c;正确的思路就是回归到自己的水平线&#xff0c;题目略难即可。 这样做题的话&#xff0c;大部分题目涉及的点不会超出自己的能力范围&…

【详识JAVA语言】String 类1

String类的重要性 在C语言中已经涉及到字符串了&#xff0c;但是在C语言中要表示字符串只能使用字符数组或者字符指针&#xff0c;可以使用标准库提 供的字符串系列函数完成大部分操作&#xff0c;但是这种将数据和操作数据方法分离开的方式不符合面相对象的思想&#xff0c;而…

python之海龟绘图

海龟绘图&#xff08;turtle&#xff09;是一个Python内置的绘图库&#xff0c;也被称为“Turtle Graphics”或简称“Turtles”。它采用了一种有趣的绘图方式&#xff0c;模拟一只小海龟在屏幕上爬行&#xff0c;而小海龟爬行的路径就形成了绘制的图形。这种绘图方式最初源自20…

考研数学——高数:多元函数微分法及其应用

因为复习阶段全篇很细节的写下来一来比较费时间&#xff0c;二容易导致为了记笔记而记。 接下来的内容只会保留上课中比较有意义的地方&#xff0c;以及有自己助于理解的想法 全微分 助记&#xff1a; 证明是否可微&#xff0c;首先判断两个偏导数是否存在&#xff0c;不存在则…

插入排序和归并排序

插入排序&#xff0c;Insertion Sort. 给出伪代码 for i 1,2,...,n-1Insert A[i] into Sorted array A[0:i-1]by swaping down to the correct position. 冒泡排序 冒泡排序就是一种插入排序算法。 i ← 1 while i < length(A)j ← iwhile j > 0 and A[j-1] > A…

FlyClient SPV client轻量化

这篇文章主要是为了构建一种轻客户端的算法。 如果使用SPV 的方式验证交易&#xff0c;每个client上面需要存储非常多的header。使用 proofs of proof-of-work 的方式&#xff0c;使得请客户端仅仅下载少量的区块头就能验证这一条链的安全性&#xff0c;然后再对包含交易的区块…

【详识JAVA语言】String类2

常用方法 字符串的不可变性 String是一种不可变对象. 字符串中的内容是不可改变。字符串不可被修改&#xff0c;是因为&#xff1a; 1. String类在设计时就是不可改变的&#xff0c;String类实现描述中已经说明了 以下来自JDK1.8中String类的部分实现&#xff1a; String类…

2D/3D相机手眼标定总结

1. 九点标定 九点标定法的本质&#xff1a; 无需进行相机内参标定&#xff0c;只能识别x&#xff0c;y坐标&#xff0c;属于2D平面标定&#xff0c;在标定过程中z是未知的。 该算法的核心是仿射变换&#xff0c;即图像坐标系到机器人坐标系的2D仿射变换&#xff08;注意这里并不…

【python--比对两个列表获取列表中出现频率最高的词及频率】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;Python &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; python练习题 完整代码 完整代码 from collections import Counter from data_keywords import extract_…

【Linux】文件传输工具lrzsz的安装与使用

目录 一、关于lrzsz 二、安装lrzsz 三、lrzsz的说明及使用 1、上传命令rz 2、下载命令sz 一、关于lrzsz 在开发的过程中&#xff0c;经常遇到 需要在 Linux 和 Windows 之间上传下载文件的情况 这时&#xff0c;一般都是使用 FTP 或者 WinSCP 工具进行上传下载, 虽然也能…

SRIO—IP讲解及说明

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、SRIO IP 概述1.1 逻辑层1.1.1 I/O 端口(I/O Port)1.1.2 消息端口(Messaing Port)1.1.3 用户自定义端口(User-Defined Port)1.1.4 维护端口(Maintenance Port)1.2 缓冲层1.3 物理层…

python+django+vue房屋租赁系统 8gwmf

房屋租赁系统在设计与实施时&#xff0c;采取了模块性的设计理念&#xff0c;把相似的系统的功能整合到一个模组中&#xff0c;以增强内部的功能&#xff0c;减少各组件之间的联系&#xff0c;从而达到减少相互影响的目的。如房源信息、预约信息、求租信息模块等[12]。 管理员后…

java工程师面试简历模板,2024谈一下当下最合适的Java架构

前言 这些算法&#xff0c;都是小编一点一点看的大佬们的方法&#xff0c;自己积累的. 如果有什么描述的不对的地方还望大佬赐教 多交流才能进步&#xff0c;加油&#xff0c;冲冲冲&#xff01;&#xff01;&#xff01; 目录 一、冒泡排序 二、选择排序 三、插入排序 四、快速…