网络编程(学习)2024.8.28

2024-08-29 07:20
文章标签 学习 编程 网络 28 2024.8

本文主要是介绍网络编程(学习)2024.8.28,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

TCP服务器代码优化

1.命令行传参

2.判错方式

3.自动绑定IP地址

4.来电显示功能

5.循环服务器

网络模型

1.网络的体系结构

2.OSI模型

3.TCP/IP模型

4.常见网络协议 

域名

1.域名系统DNS

2.域名结构

3.DNS工作流程

虚拟机网络

(1)虚拟机NAT模式

(2)虚拟机桥接模式

网络调试

1.ping

2.路由探测

3.网速检测

4.netstat

UDP编程

通信流程

接收数据recvfrom 

发送数据sendto 

FTP仿写练习

TCP服务器代码优化

1.命令行传参

通过命令行传入IP和端口号,并加入判错

2.判错方式

#define ERR_MSG(msg)

do{        \
        fprintf(stderr, "line:%d ", __LINE__);        \ 
        perror(msg);        \
}while(0)

出现错误时会顺便把第几行出错给打印出来,使用将之前使用perror()的部分改为ERR_MSG()即可,例如perror(“bind失败”);可以写为ERR_MSG(“bind失败”);

3.自动绑定IP地址

    // saddr.sin_addr.s_addr = inet_addr("192.168.50.213");
#if 0saddr.sin_addr.s_addr = inet_addr("0.0.0.0");
#elsesaddr.sin_addr.s_addr = INADDR_ANY;
#endif

4.来电显示功能

当接收到客户端连接请求时,连接打印客户端的ip和端口号

printf("acceptfd:%d\n", acceptfd);
printf("客户端ip:%s\t 端口号:%d\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));

5.循环服务器

一对一连接,一个客户端退出后,下一个客户端可以进行连接。

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>#define ERR_MSG(msg)                           \do                                         \{                                          \fprintf(stderr, "line:%d ", __LINE__); \perror(msg);                           \} while (0)int main(int argc, char const *argv[])
{if (argc != 2){printf("用法:<port>\n");return -1;}// 1.创建套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);printf("sorkfd:%d\n", sockfd);// 2.bind绑定IP和Port端口号struct sockaddr_in saddr, caddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(atoi(argv[1]));// saddr.sin_addr.s_addr = inet_addr("192.168.50.213");socklen_t addrlen = sizeof(saddr);
#if 0saddr.sin_addr.s_addr = inet_addr("0.0.0.0");
#elsesaddr.sin_addr.s_addr = INADDR_ANY;
#endifif (bind(sockfd, (struct sockaddr *)&saddr, addrlen) < 0){ERR_MSG("bind失败");return -1;}printf("bind成功\n");// 3.监听listen将主动套接字变为被动套接字if (listen(sockfd, 7) < 0){ERR_MSG("lisren失败");return -1;}printf("listen成功\n");while (1){// 4.accept阻塞等待链接int acceptfd = accept(sockfd, (struct sockaddr *)&caddr, &addrlen);if (acceptfd < 0){ERR_MSG("accept失败\n");return -1;}printf("acceptfd:%d\n", acceptfd);printf("客户端ip:%s\t 端口号:%d\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));// 5.发送
#define N 64char buf[N];while (1){memset(buf, 0, N);int ret = recv(acceptfd, buf, N, 0);if (ret < 0){perror("recv失败\n");return -1;}else if (ret == 0){printf("客户端ip:%s退出\n", inet_ntoa(caddr.sin_addr));close(acceptfd);break;}else{printf("客户端%s\n", buf);}}}close(sockfd);return 0;
}

网络模型

1.网络的体系结构

网络采用分而治之的方法设计,将网络的功能划分为不同的模块,以分层的形式有机组合在一起。
每层实现不同的功能,其内部实现方法对外部其他层次来说是透明的。每层向上层提供服务,同时使用下层提供的服务
网络体系结构即指网络的层次结构和每层所使用协议的集合
两类非常重要的体系结构:OSI与TCP/IP

分层的好处:

1.各层之间独立,每一层不需要知道下一层如何实现,而仅仅只需要知道该层通过层间的接口所提供的的服务。
2.稳定,当任何一层发生变化时,只要层间接口关系保持不变,则这层以上或以下层不受影响。
3.易于实现和维护
4.促进标准化工作

2.OSI模型

●OSI模型是一个理想化的模型,尚未有完整的实现
●OSI模型共有七层:

        应用层,表示层,会话层,传输层,网络层,数据链路层,物理层
●OSI现阶段只用作教学和理论研究 

3.TCP/IP模型

在网络中传输的数据,不仅仅有用户发送的数据,还包含着其他的必要信息,比如对端的IP和端口号

TCP/IP模型四层:
应用层:应用协议和应用程序的集合。
传输层:端到端 ,写入源端口和目的端口决定数据交给机器的哪个任务(进程)去处理,通过端口寻址,TCP和UDP等协议
网络层:提供设备对设备的传输,可以理解为通过IP寻找机器,IP地址
网络接口和物理层:屏蔽硬件差异(驱动),向上层提供统一的操作接口,网线。

TCP/IP模型五层:

应用层,传输层,网络层,数据链路层,物理层.

4.常见网络协议 

网络接口和物理层:
        ppp:拨号协议(老式电话线上网方式)
        ARP:地址解析协议  IP-->MAC
        RARP:反向地址转换协议 MAC-->IP
网络层:    
        IP(IPV4/IPV6):网间互连的协议
        ICMP:网络控制管理协议,ping命令使用
        IGMP:网络分组管理协议,广播和组播使用
传输层:
        TCP:传输控制协议
        UDP:用户数据报协议
应用层:
        SSH:加密协议
        telnet:远程登录协议
        FTP:文件传输协议
        HTTP:超文本传输协议
        Modbus_Tcp 
        DNS:地址解析协议
        SMTP/POP3:邮件传输协议

注意:TCP和IP是属于不同协议栈层的,只是这两个协议属于协议族里最重要的协议,所以协议栈或者模型以之命名了。

域名

1.域名系统DNS

由于使用IP地址来指定计算机不方便人们记忆,且输入时候容易出错,用字符标识网络中计算机名称方法。
这种命名方法就像每个人的名字,这就是域名(Domian Name )
域名服务器(Domain Name server):用来处理IP地址和域名之间的转换。
域名系统(Domain Name System,DNS):域名翻译成IP地址的软件DNS

2.域名结构

例如域名 www.baidu.com.cn       从右向左看
    cn为高级域名,也叫一级域名,它通常分配给主干节点,取值为国家名,cn代表中国
    com为网络名,属于二级域名,它通常表示组织或部门
    中国互联网二级域名共40个,edu表示教育部门,com表示商业部门,gov表示政府,军队mil等等
    baidu为机构名,在此为三级域名,表示百度
    www:万维网world wide web,也叫环球信息网,是一种特殊的信息结构框架。

3.DNS工作流程

主机发送域名到DNS服务器,DNS服务器接受域名返回对应的ip地址给主机,然后主机通过ip的地址访问对应的服务器

虚拟机网络

(1)虚拟机NAT模式

Net模式下,虚拟机的IP由宿主主机分配,不定。
虚拟机的IP网段不定,甚至会分配到同一个ip,每个虚拟机都由宿主虚拟出来的DHCP服务器分配IP,互相不能通信。

(2)虚拟机桥接模式

桥接模式下,虚拟机的ip由路由器分配,所以虚拟机在路由器网关的地位就相当于和宿主主机处于并列地位,故正常主机有的通信功能它都会有。

网络调试

1.ping

ping的作用主要为:
● 用来检测网络的连通情况;
● 根据域名得到服务器IP;
● 根据ping返回的TTL值来判断数据包经过路由器数量。

字节:数据包大小,也就是字节。
时间:响应时间,这个时间越小,说明你连接这个地址速度越快。
TTL:Time To Live,从源到目的,每经过一个路由器,TTL减1,当TTL=0,包丢掉。(TTL的初值跟操作系统挂钩,TTL初值根据操作系统的具体版本不同会有所区别)

2.路由探测

tracert 域名

3.网速检测

https://www.speedtest.cn/

4.netstat

netstat是控制台命令,是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息。Netstat用于显示与IP、TCP、UDP相关的统计数据,一般用于检验本机各端口的网络连接情况。
作用:测试网络状态
        netstat -a        //查看所有网络连接状态
        netstat -at        //查看tcp所有网络状态
        netstat -au        //查看udp所有网络状态

可以使用联合命令查询
netstat -at | grep 8888        //代表查看所有端口和8888有关的TCP连接状态

UDP编程

不同:

TCP面向连接,可靠 ,速度慢  
UDP无连接不可靠,速度快

通信流程

服务器:1.创建套接字socket()

                2.绑定bind()

                3.recvform()

                4.sendto()

udp_server.c:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>#define ERR_MSG(msg)                           \do                                         \{                                          \fprintf(stderr, "line:%d ", __LINE__); \perror(msg);                           \} while (0)int main(int argc, char const *argv[])
{// 1.创建套接字int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){ERR_MSG("创建套接字失败\n");return -1;}// 2.bind绑定IP和Port端口号struct sockaddr_in saddr, caddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(atoi(argv[1]));// saddr.sin_addr.s_addr = inet_addr("192.168.50.213");socklen_t addrlen = sizeof(saddr);
#if 0saddr.sin_addr.s_addr = inet_addr("0.0.0.0");
#elsesaddr.sin_addr.s_addr = INADDR_ANY;
#endifif (bind(sockfd, (struct sockaddr *)&saddr, addrlen) < 0){ERR_MSG("bind失败");return -1;}printf("bind成功\n");// 3.接收消息
#define N 64char buf[N];while (1){int ret = recvfrom(sockfd, buf, N, 0, (struct sockaddr *)&caddr, &addrlen);if (ret < 0){ERR_MSG("接收消息失败\n");close(sockfd);return -1;}else{printf("客户端ip:%s:%s\n", inet_ntoa(caddr.sin_addr), buf);}// 4.回复sendto(sockfd, buf, N, 0, (struct sockaddr *)&caddr, addrlen);}close(sockfd);return 0;
}

客户端:1.创建套接字socket()

                2. sendto()

                3.recvform()              

 udp_client.c:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>#define ERR_MSG(msg)                           \do                                         \{                                          \fprintf(stderr, "line:%d ", __LINE__); \perror(msg);                           \} while (0)int main(int argc, char const *argv[])
{// 1.创建套接字int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){ERR_MSG("创建套接字失败\n");return -1;}unsigned short post = 0;char ip[15];printf("请输入ip地址");scanf("%s", ip);getchar();printf("请输入端口号");scanf("%hd", &post);getchar();struct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(post);saddr.sin_addr.s_addr = inet_addr(ip);socklen_t addrlen = sizeof(saddr);
#define N 64char buf[N];while (1){memset(buf, 0, N);printf("请输入要输入的数据:");scanf("%s", buf);getchar();if (strcmp(buf, "quit") == 0){printf("客户端退出\n");break;}sendto(sockfd, buf, N, 0, (struct sockaddr *)&saddr, addrlen);}close(sockfd);return 0;
}

接收数据recvfrom 

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr,socklen_t *addrlen);
功能:接收数据

参数:
        sockfd:套接字描述符
        buf:接收缓存区的首地址
        len:接收缓存区的大小
        flags:0
        src_addr:发送端的网络信息结构体的指针
        addrlen:发送端的网络信息结构体的大小的指针
返回值:
        成功:返回接收的字节个数
        失败:-1
        0:客户端退出

发送数据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
        src_addr:接收端的网络信息结构体的指针
        addrlen:接收端的网络信息结构体的大小

返回值: 
        成功:返回发送的字节个数
        失败:-1

FTP仿写练习

基于TCP连接模拟FTP核心原理:客户端连接服务器后,向服务器发送一个文件。发送和接收的文件名可以通过参数指定,服务器端接收客户端传来的文件并存储(文件大小不确定,不能一包发过去);如果文件不存在自动创建文件,如果文件存在,那么清空文件然后写入,文件的名字随意。

ftpserver.c:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>#define ERR_MSG(msg)                           \do                                         \{                                          \fprintf(stderr, "line:%d ", __LINE__); \perror(msg);                           \} while (0)int main(int argc, char const *argv[])
{if (argc != 3){printf("用法:<存放地址> <端口号>\n");return -1;}// 1.创建套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){ERR_MSG("创建套接字失败\n");return -1;}// 2.bind绑定IP和Port端口号struct sockaddr_in saddr, caddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(atoi(argv[2]));saddr.sin_addr.s_addr = inet_addr("192.168.50.213");socklen_t addrlen = sizeof(saddr);if (bind(sockfd, (struct sockaddr *)&saddr, addrlen) < 0){ERR_MSG("bind失败");return -1;}printf("bind成功\n");// 3.监听listen将主动套接字变为被动套接字if (listen(sockfd, 7) < 0){ERR_MSG("lisren失败");return -1;}printf("listen成功\n");// 4.accept阻塞等待链接int acceptfd = accept(sockfd, (struct sockaddr *)&caddr, &addrlen);if (acceptfd < 0){ERR_MSG("accept失败\n");return -1;}printf("acceptfd:%d\n", acceptfd);printf("客户端ip:%s\t 端口号:%d\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));// 4.接受int fd;fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0666);if (fd < 0){perror("文件打开失败\n");return -1;}char buf[64];while (1){int ret = recv(acceptfd, buf, sizeof(buf), 0);if (ret < 0){perror("recv失败\n");return -1;}else if (ret == 0){printf("客户端ip:%s退出\n", inet_ntoa(caddr.sin_addr));close(acceptfd);break;}else{write(fd, buf, ret);}}printf("接收成功\n");close(sockfd);return 0;
}

ftpclient.c:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>#define ERR_MSG(msg)                           \do                                         \{                                          \fprintf(stderr, "line:%d ", __LINE__); \perror(msg);                           \} while (0)int main(int argc, char const *argv[])
{if (argc != 4){printf("用法:<文件地址> <ip地址> <端口号>\n");return -1;}// 1.创建套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){ERR_MSG("创建套接字失败\n");return -1;}// 2.连接unsigned short post = 0;char ip[15];struct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(atoi(argv[3]));saddr.sin_addr.s_addr = inet_addr(argv[2]);socklen_t addrlen = sizeof(saddr);if (connect(sockfd, (struct sockaddr *)&saddr, addrlen) < 0){perror("connect失败\n");return -1;}// 3.发送int fd;fd = open(argv[1], O_RDONLY);if (fd < 0){perror("文件打开失败\n");return -1;}
#define N 64char buf[N];ssize_t s;while (1){s = read(fd, buf, sizeof(buf));if (s == 0){break;}send(sockfd, buf, sizeof(buf), 0);}printf("文件发送成功\n");close(sockfd);return 0;
}

这篇关于网络编程(学习)2024.8.28的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1117214

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学