您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

网络编程——协议基础

时间:2020-07-09 18:51:11  来源:  作者:

本篇包括网络编程概述、UDP简介、TFTP简介、TCP编程等。

目录

一、tcp/ip协议简介

二、端口

三、IP地址

四、mac地址

五、socket简介

六、UDP网络通信过程

七、模拟QQ聊天-多线程实现

八、wireshark抓包工具的使用

九、tftp下载器的使用(tftpd64或tftpd32)

十、UDP广播

十一、TCP服务器、客户端简介及实现

11.1 TCP简介

11.2 TCP和UDP通信模型

11.3 Python实现tcp服务器和客户端

一、tcp/ip协议简介

tcp/ip不是两个协议,而是一个协议组,实际为4层,逻辑上可以为7层,如下图所示:

网络编程——协议基础

 

二、端口

为什么使用端口?只有ip地址时只知道发往哪个电脑而不知道发往哪个程序,端口用来辨识要发往的具体程序。

为什么不用PID辨识进程?因为进程是动态的,远端电脑可能不知道本地的pid号。

知名端口:大家都知道的约定好的端口,如80端口为HTTP服务,21端口为FTP服务,范围为0~1023。

动态端口:用户自己定义的端口,范围为1024~65535.

查看端口命令:.NETstat -an

注意:在同一个OS中,端口不允许相同,如果某个端口已经被使用了,那么在这个进程释放这个端口之前,其他进程不能使用这个端口。因为端口用来区分一个进程。

网络编程——协议基础

 

三、IP地址

用来逻辑上表示网络上的唯一一台电脑。

注意:一个电脑可以有多个网卡,即多个IP地址!

IP地址分类

其中网络号固定不变,表示位于同一网络中的电脑,主机号为当前网络中的电脑号。

主机号为0时表示网段号,主机号为255时为网关。

D类用于多播(不是广播),例如视频会议,只有一些人可以看到。

E类实验和开发用。

网络编程——协议基础

 

私有ip

用于局域网中,访问公网时不能使用,需要转换为公有ip访问外网。范围如下:

网络编程——协议基础

 

注意

IP地址127.0.0.1~127.255.255.255用于回路测试,即测试当前电脑tcp/ip协议能不能用,例如ping 127.0.0.1,即使拔掉网线也能ping得通。

linux服务器开发学习视频资料,包括Linux,Nginx,ZeroMQ,MySQLredis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等等。

需要知识技术学习视频文档资料的朋友可以后台私信【架构】获取

网络编程——协议基础

 


网络编程——协议基础

 

四、MAC地址

网卡的序列号,形如XX:XX:XX:XX:XX:XX,六组十六进制数,前三组表示厂商序列号,后三组表示网卡序列号。

五、socket简介

socket:通过网络使进程间通信。

注意:一个进程可以有多个socket!

python测试程序如下:

网络编程——协议基础

 

端口绑定(只能绑定自己的端口!)

上面程序每次运行时操作系统为它分配的端口不一样,这导致了远端电脑不知道每次运行的端口,不能发送信息到本地。

python程序如下:

注意:bindAddr中第一个参数为空,因为该参数表示本地IP地址,但本地可能有多个IP,空表示任意ip都进行绑定。

网络编程——协议基础

 

六、UDP网络通信过程

应用层填写需要发送的数据;传输增加上端口号等;网络层加上目的ip等;链路层加上目的mac等;如下图:

网络编程——协议基础

 

七、模拟QQ聊天-多线程实现

全双工实现QQ聊天,代码如下:

from threading import Thread

from socket import *

 

#1. 收数据,然后打印

def recvData():

while True:

recvInfo = udpSocket.recvfrom(1024)

print(">>%s:%s"%(str(recvInfo[1]), recvInfo[0]))

 

#2. 检测键盘,发数据

def sendData():

while True:

sendInfo = input("<<")

udpSocket.sendto(sendInfo.encode("gb2312"), (destIp, destPort))

 

udpSocket = None

destIp = ""

destPort = 0

 

def main():

 

global udpSocket

global destIp

global destPort

 

destIp = input("对方的ip:")

destPort = int(input("对方的ip:"))

 

udpSocket = socket(AF_INET, SOCK_DGRAM)

udpSocket.bind(("", 4567))

 

tr = Thread(target=recvData)

ts = Thread(target=sendData)

 

tr.start() #启动接收数据线程

ts.start() #启动发送数据线程

 

tr.join() #等待两个线程结束

ts.join()

 

if __name__ == "__main__":

main()

八、wireshark抓包工具的使用

wireshark工具可以抓取当前电脑中所有网络数据,具体如图所示:

网络编程——协议基础

 

九、tftp下载器的使用(tftpd64或tftpd32)

tftp是tcp/ip协议族中用来将客户端和服务器之间进行简单文件传输的协议。

特点如下:

基于UDP实现,可能会丢包,实现过程为收到-回复,下载过程如下:

网络编程——协议基础

 

TFTP数据表格式如下:

读写请求格式:操作码为1或2,分别表示读或写;文件名为文件名称;0为固定写法;模式有几种,最常用的为octet;最后跟一个0。

数据表格式:操作码固定为3;文件名为文件名称;块编号为文件分割的块编号;数据为详细数据。

确认格式:操作码固定为4;块编号为确认收到的文件分块编号。

错误表格式:操作码固定为5;差错码为固定好的错误编号;后面接具体差错信息;最后跟一个0;

注意:确认包发往的是服务器发送本地进程时分配的随机端口!

怎样确定数据已经发送完毕了?

规定, 当客户端接收到的数据⼩于516(2字节操作码+2个字节的序号+512字节数据) 时, 就意味着服务器发送完毕了。

怎样保证包中每个码的字节数?

python中组包代码如下:

网络编程——协议基础

 

!:表示网络中的数据,网络中的数据用大端表示。

H:占用2个字节,对应后面的1。

8s:占用8个字节,对应后面的"test.jpg"。

b:占用1个字节,对应后面的0。

5s:占用5个字节,对应后面的"octet"。

b:占用1个字节,对应后面的0。

表格式如图所示:

网络编程——协议基础

 

使用python从tftp服务器中下载文件

1)首先启动tftpd64应用程序,设置好下载的目录和ip地址。

2)python代码如下:

# -*- coding:utf-8 -*-

 

import struct

from socket import *

import time

import os

 

def main():

 

#0. 获取要下载的文件名字:

downloadFileName = raw_input("请输入要下载的文件名:")

 

#1.创建socket

udpSocket = socket(AF_INET, SOCK_DGRAM)

 

requestFileData = struct.pack("!H%dsb5sb"%len(downloadFileName), 1, downloadFileName, 0, "octet", 0)

 

#2. 发送下载文件的请求

udpSocket.sendto(requestFileData, ("192.168.119.215", 69))

 

flag = True #表示能够下载数据,即不擅长,如果是false那么就删除

num = 0

f = open(downloadFileName, "w")

 

while True:

#3. 接收服务发送回来的应答数据

responseData = udpSocket.recvfrom(1024)

 

# print(responseData)

recvData, serverInfo = responseData

 

opNum = struct.unpack("!H", recvData[:2])

 

packetNum = struct.unpack("!H", recvData[2:4])

 

print(packetNum[0])

 

# print("opNum=%d"%opNum)

# print(opNum)

 

# if 如果服务器发送过来的是文件的内容的话:

if opNum[0] == 3: #因为opNum此时是一个元组(3,),所以需要使用下标来提取某个数据

 

#计算出这次应该接收到的文件的序号值,应该是上一次接收到的值的基础上+1

num = num + 1

 

# 如果一个下载的文件特别大,即接收到的数据包编号超过了2个字节的大小

# 那么会从0继续开始,所以这里需要判断,如果超过了65535 那么就改为0

if num==65536:

num = 0

 

# 判断这次接收到的数据的包编号是否是 上一次的包编号的下一个

# 如果是才会写入到文件中,否则不能写入(因为会重复)

if num == packetNum[0]:

# 把收到的数据写入到文件中

f.write(recvData[4:])

num = packetNum[0]

 

#整理ACK的数据包

ackData = struct.pack("!HH", 4, packetNum[0])

udpSocket.sendto(ackData, serverInfo)

 

elif opNum[0] == 5:

print("sorry,没有这个文件....")

flag = False

 

# time.sleep(0.1)

 

if len(recvData)<516:

break

 

if flag == True:

f.close()

else:

os.unlink(downloadFileName)#如果没有要下载的文件,那么就需要把刚刚创建的文件进行删除

 

if __name__ == '__main__':

main()

十、UDP广播

UDP广播不是对每个用户轮流发送数据,而是发送到交换机,交换机负责同时发送给每个用户。

广播可用于动态获取ip地址。

单播----点对点;多播----一对多;广播----一无所有。

注意:广播只用于UDP中,TCP不能广播!

python简单实现:

网络编程——协议基础

 

十一、TCP服务器、客户端简介及实现

11.1 TCP简介

tcp:传输控制协议

特点:1、稳定;2、相对udp而言要慢一些;3、web服务器都是使用的tcp;

udp:用户数据包协议

特点:1、不稳定;2、相对tcp而言要快一些;

11.2 TCP和UDP通信模型

udp通信模型:相当于写信;

网络编程——协议基础

 

tcp通信模型:相当于打电话;

socket创建出来的套接字,默认为主动套接字,即发送数据给别人。listen()将主动套接字变为被动套接字。

TCP服务器端:

1、买个手机 socket(xxx);

2、插入手机卡 bind(xxx);

3、设置手机为响铃模式 listen();

4、等待别人的电话,准备好接听 accept();

TCP客户端:

1、买个手机 socket(xxx);

2、拨打电话 connect(xxx);

网络编程——协议基础

 

11.3 python实现tcp服务器和客户端

tcp服务器端实现(简单原理实现,非实际的多进程)如下:

注意:

accept用来接收客户端请求,并重新创建一个socket为新的客户服务,然后等待下一个客户端的请求。

clientSocket用来专门为新的客户端服务。

代码解释:

第一个while循环用来监听是否有新客户接入,并为它分配服务资源。

第二个while循环为新的客户端服务。注意:当客户端下线时,newSocket.recv(1024)这句可以解阻塞,且返回值为0,从而可以跳出循环。

该程序为单任务,实际服务器为多进程实现,只需将第二个while定义为一个函数,在第一个while中启动一个进程执行该函数即可。

#coding=utf-8

from socket import *

# 创建socket

tcpSerSocket = socket(AF_INET, SOCK_STREAM)

# 绑定本地信息

address = ('', 7788)

tcpSerSocket.bind(address)

 

# 使⽤socket创建的套接字默认的属性是主动的, 使⽤listen将其变为被动的, 这样就可以接收。

# 5表示服务器同一时刻最多允许5个客户端发数据

tcpSerSocket.listen(5)

 

while True:

# 如果有新的客户端来连接服务器, 那么就产⽣⼀个新的套接字专⻔为这个客户端服务器

# newSocket⽤来为这个客户端服务

# tcpSerSocket就可以省下来专⻔等待其他新客户端的链接

newSocket, clientAddr = tcpSerSocket.accept()

 

# 该循环为新的客户端服务。注意:当客户端下线时,newSocket.recv(1024)这句可以解阻塞,且返回

# 值为0,从而可以跳出循环

while True:

# 接收对⽅发送过来的数据, 最⼤接收1024个字节

recvData = newSocket.recv(1024)

 

# 如果接收的数据的⻓度为0, 则意味着客户端关闭了链接

if len(recvData)>0:

print 'recv:',recvData

else:

break

 

# 发送⼀些数据到客户端

sendData = raw_input("send:")

newSocket.send(sendData)

 

# 关闭为这个客户端服务的套接字, 只要关闭了, 就意味着为不能再为这个客户端服务了

newSocket.close()

 

# 关闭监听套接字, 只要这个套接字关闭了, 就意味着整个程序不能再接收任何新的客户端的连接

tcpSerSocket.close()

tcp客户器端实现如下:

from socket import *

 

#创建TCP套接字

clientSocket = socket(AF_INET, SOCK_STREAM)

#链接服务器

clientSocket.connect(("192.168.119.153", 8989))

 

#注意:

# 1. tcp客户端已经连接好了服务器,所以在以后的数据发送中,不需要填写对方的iph和port----->打电话

# 2. udp在发送数据的时候,因为没有之前的链接,所以需要 在每次的发送中 都要填写接收方的ip和port----->写信 

 

#发送数据

clientSocket.send("haha".encode("gb2312"))

#接收数据

recvData = clientSocket.recv(1024)

#打印接收到的数据

print("recvData:%s"%recvData)

#关闭客户端socket

clientSocket.close()



Tags:网络编程   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
引言本期分享一个比较常见的网络问题--丢包。例如我们去ping一个网站,如果能ping通,且网站返回信息全面,则说明与网站服务器的通信是畅通的,如果ping不通,或者网站返回的信息不全...【详细内容】
2022-04-21  Tags: 网络编程  点击:(235)  评论:(0)  加入收藏
之前介绍了网络字节序。网络编程之网络字节序详解今天就来实现一下简单的网络程序。先看几个函数// 创建socket套接字int socket(int domain, int type, int protocol);//...【详细内容】
2022-03-17  Tags: 网络编程  点击:(90)  评论:(0)  加入收藏
IP地址和端口号1)IP地址用来标志网络中的一个通信实体的地址。通信实体可以是计算机,路由器等。2)IP地址分类IPV4:32位地址,以点分十进制表示,如192.168.0.1IPV6:128位(16个字节)写成...【详细内容】
2022-03-17  Tags: 网络编程  点击:(92)  评论:(0)  加入收藏
目录4、TCP网络传输的基本流程二、网络编程套接字(socket)5、cookie和session的用法6、基本实现http协议的代码四、传输层协议TCP和UDP4、TCP和UDP之间的对比六、数据链路层和...【详细内容】
2022-01-04  Tags: 网络编程  点击:(144)  评论:(0)  加入收藏
本系列为 Netty 学习笔记,本篇介绍总结Java NIO 网络编程。Netty 作为一个异步的、事件驱动的网络应用程序框架,也是基于NIO的客户、服务器端的编程框架。其对 Java NIO 底层...【详细内容】
2021-12-07  Tags: 网络编程  点击:(80)  评论:(0)  加入收藏
当初写第一个网络程序的时候,就是通过搜索,找各种实例把程序拼凑出来的,并没有进行深入的理解。这个东西用了这么多年,是该来沉淀一下了,也检验一下自己对这块知识的掌握程度。可...【详细内容】
2021-10-18  Tags: 网络编程  点击:(139)  评论:(0)  加入收藏
网络工程领域不断出现新的协议、技术、交付和运维模式。传统网络面临着云计算、人工智能等新连接需求的挑战。企业也在不断追求业务的敏捷、灵活和弹性。在这些背景下,网络自...【详细内容】
2021-02-03  Tags: 网络编程  点击:(280)  评论:(0)  加入收藏
计算机网络计算机网络是指由通信线路互相连接的许多独立自主工作的计算机构成的资源共享集合体。 计算机网络作用:资源共享。 计算机网络组成:许多独立自主工作的计算机。 计...【详细内容】
2020-12-01  Tags: 网络编程  点击:(146)  评论:(0)  加入收藏
Linux网络编程API函数初步剖析今天我们来分析一下前几篇博文中提到的网络编程中几个核心的API,探究一下当我们调用每个API时,内核中具体做了哪些准备和初始化工作。 1、socket...【详细内容】
2020-11-03  Tags: 网络编程  点击:(87)  评论:(0)  加入收藏
01.为何会有HttpsHttp的缺点通信使用明显通信使用明显意味着安全性大大降低,当通信过程被窃听后,无需花费额外的投入就可看到传输的数据。例如使用抓包工具,无需任何配置就可...【详细内容】
2020-09-26  Tags: 网络编程  点击:(82)  评论:(0)  加入收藏
▌简易百科推荐
1. 前言了解响应式编程,首先我们需要了解函数式操作和Stream的操作,下面我们简单的复习一下喽。1.1 常用函数式编程函数式接口中我们先来回顾一下Java中的函数式接口。常见的...【详细内容】
2022-07-15  二哥学Java    Tags:编程   点击:(1)  评论:(0)  加入收藏
在本文中,我们将学习如何使用 Next.js、 Prisma、 Postgres 和 Fastify 构建一个 Full-stack 应用程序。在本文中,我们将学习如何使用 Next.js、 Prisma、 Postgres 和 Fastif...【详细内容】
2022-07-12  qaseven    Tags:全栈   点击:(9)  评论:(0)  加入收藏
好的软件开发网站有哪些?做软件开发哪些网站能提供帮助呢?这些很多做软件开发的小伙伴都会问到的问题。007出海全球社交流量导航网站,整合了多方出海跨境网站资源,为你介绍出海...【详细内容】
2022-07-08  Chuhai007    Tags:软件开发   点击:(10)  评论:(0)  加入收藏
我们用monkey做压力测试后,会保存一个monkey日志,那如果想快速的分析日志中有哪些异常,我们可以用批处理工具进行快速的筛查,我们一起来看看吧。先编写个小脚本,然后修改为bat后...【详细内容】
2022-07-08  溪流涌动    Tags:monkey   点击:(13)  评论:(0)  加入收藏
白盒测试落地实践分为两个大方向,一个是静态分析,一个是动态分析,当然啦,也可以叫做静态测试和动态测试。那我们如何高质量保效率的做好白盒测试呢?Parasoft已经为您准备好了成熟...【详细内容】
2022-07-08  Parasoft中国    Tags:白盒测试   点击:(11)  评论:(0)  加入收藏
Altium Designer 自带脚本功能的开发项目,可以调用官方AD API接口对原理图或者PCB进行自动操作,本文主要分享开发的流程,和一些基本的概念信息,本文介绍的脚本工具例子可以用在P...【详细内容】
2022-07-07  电子工程师伟哥    Tags:Altium Designer   点击:(21)  评论:(0)  加入收藏
一、目录介绍 前置知识点 NIO Netty 的核心组件 Channel Callback Future 和 Promise 事件和 ChannelHandler Hello World二、前置知识点1、NIO首先我们需要回顾一...【详细内容】
2022-07-06  架构师jickly    Tags:聊天系统   点击:(16)  评论:(0)  加入收藏
1.事件流事件流是对事件执行过程的描述,了解事件的执行过程有助于加深对事件的理解,提升开发实践中对事件运用的灵活度。2.捕获和冒泡捕获阶段是【从父到子】的传导过程,冒泡阶...【详细内容】
2022-07-06  金乾坤    Tags:API   点击:(13)  评论:(0)  加入收藏
刷盘策略CommitLog的asyncPutMessage方法中可以看到在写入消息之后,调用了submitFlushRequest方法执行刷盘策略:public class CommitLog { public CompletableFuture<PutMe...【详细内容】
2022-07-06  Java码农之路    Tags:RocketMQ   点击:(16)  评论:(0)  加入收藏
最近读了本好书-《深度学习推荐系统》,读完不觉全身通畅,于是就有了写这篇文章的想法,把自己的理解和总结分享给大家。 本文将按照从算法到工程的顺序,先介绍一下推荐系统整体...【详细内容】
2022-07-05  InfoQ    Tags:推荐系统   点击:(22)  评论:(0)  加入收藏
站内最新
站内热门
站内头条