Python网络编程

TCP 客户端与服务器之间建立连接需要进行三次握手 客户端--->服务器  服务器--->客户端  客户端--->服务器,这样做的好处是可以保证数据的完整缺点是慢.

  • UDP 是用户数据报协议,传输模式是数据报,

  • UDP 是无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。

  • UDP 是简单不可靠的协议,它不提供可靠性,只是把数据包发送出去,并不保证能够到达目的地。由于它不需要在客户端和服务端之间建立连接,也没有超时重发机制,所以传输速度很快。

UDP 不需要进行三次握手,客户端与服务器之间直接往对方脸上丢数据不管有没有接到,优点是快缺点是无法保证数据的完整.

UDP数据包一般包含512个字节,当大于512字节时,可能会出现传输不稳定的情况。

  • UDP每个发送的数据都含所有自身的报头,不像TCP那样是流式的数据,所以不存在粘包现象。

  • udp的recvfrom是阻塞的,一个recvfrom(x)必须对唯一一个sendto(y),收完了x个字节的数据就算完成,若是y>x数据就丢失,这意味着udp根本不会粘包,但是会丢数据,不可靠。

  • tcp 协议的数据不会丢,没有收完的包下一次会接着收取上一次没收完的数据,本端总是在收到ack时才会清除缓冲区内容。数据是可靠的,但是会粘包。

什么是socket:

这是为了实现以上的通信过程而建立成来的通信管道,其真实的代表是客户端和服务器端的一个通信进程,双方进程通过socket进行通信,而通信的规则采用指定的协议。socket只是一种连接模式,不是协议,tcp,udp,简单的说(虽然不准确)是两个最基本的协议,很多其它协议都是基于这两个协议如,http就是基于tcp的,.用socket可以创建tcp连接,也可以创建udp连接,这意味着,用socket可以创建任何协议的连接,因为其它协议都是基于此的。

UDP 传输的流程图


第一步导入网络编程的库,自带的

import socket

接着就是要调用一个方法

socket.socket(AddressFamily, Type)

就解释一下参数,别的就不说了

  • Address Family:可以选择 AF_INET(用于 Internet 进程间通信) 或者 AF_UNIX(用于同一台机器进程间通信),实际工作中常用AF_INET

  • Type:套接字类型,可以是 SOCK_STREAM(流式套接字,主要用于 TCP 协议)或者 SOCK_DGRAM(数据报套接字,主要用于 UDP 协议)

前面的名字,按照自己的喜好来


import socket
# 创建udp socketudp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# ...# 使用套接字收/发数据
# 关闭socketudp_socket.close()

上面的代码就是对于UDP的一次完整的调用

套接字使用流程 与 文件的使用流程很类似:

1.创建套接字

2.使用套接字收/发数据

3.关闭套接字

## Tello Python3 Control Demo#import threadingimport socketimport sysimport timehost = ''port = 9000locaddr = (host, port)# Create a UDP socketsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)tello_address = ('192.168.10.1', 8889)sock.bind(locaddr)def recv(): count = 0 while True: try: data, server = sock.recvfrom(1518) print(data.decode(encoding="utf-8")) except Exception: print('\nExit . . .\n')            breakprint('\r\n\r\nTello Python3 Demo.\r\n')print('Tello: command takeoff land flip forward back left right \r\n       up down cw ccw speed speed?\r\n')print('end -- quit demo.\r\n')# recvThread createrecvThread = threading.Thread(target=recv)recvThread.start()while True: try:        msg = input("") if not msg:            break if 'end' in msg: print('...') sock.close()            break # Send data msg = msg.encode(encoding="utf-8") sent = sock.sendto(msg, tello_address) except KeyboardInterrupt: print('\n . . .\n') sock.close()        break

我直接给出一个实例,这是连接Dji教育无人机的一段代码,很完整了已经

sock.bind(locaddr)

使用bind公开一个端口,使得client可以方便连接

创建了一个无人机的地址,IP+端口

可以看到上面的tello_address是作为一个参数的函数使用.

# 发送数据 send_addr = ('192.168.92.190', 7878) udp_socket.sendto(send_data.encode('GBK'), send_addr)

如果是字符集在两个目标上面不一样,还可以去更改编码模式

此时先下载一个调试工具,随便下载

import socket

def main(): # 创建套接字 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 读取输入的数据 send_data = input('请输入要发送的数据:')
# 发送数据 send_addr = ('192.168.92.190', 7878) udp_socket.sendto(send_data.encode('GBK'), send_addr)
# 关闭 udp_socket.close()

if __name__ == '__main__': main()
http://www.zlmcu.com/document/tcp_debug_tools.html

我上面的软件没有调试出来,我换了一个软件,调试成功

这个地方用wireshark看一下

选择内部的回环接口

设置这里看见是BSD

这个地方输入三个1,a,b

位置信息

可以看到是这个地址确实发了三次信息

打开看看

数据31,长度1

可以用ifconfig看看自己的ip

import socket
def main():
# 创建套接字 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定一个本地信息 localaddr = ("", 8080) udp_socket.bind(localaddr)
# 接收数据 recv_data = udp_socket.recvfrom(1024)
# recv_data是一个元组(接收到的数据, (发送方的IP, port)) recv_msg = recv_data[0] # 存储接收到的数据 send_addr = recv_data[1] # 存储发送方的地址
# 打印收到的消息 # print(recv_data) print("%s:%s" % (str(send_addr), recv_msg.decode('GBK')))
# 关闭 udp_socket.close()
if __name__ == '__main__': main()

这段代码是接收代码,写的很明白

udp端口绑定

  • 一个udp网络程序,运行时没有绑定端口,系统会给它分配一个随机的端口,如果再次运行,端口可能发生变化

  • 一个udp网络程序,也可以绑定信息(ip地址,端口号),如果绑定成功,那么操作系统用这个端口号来进行区别收到的网络数据是否是此进程的

什么时候需要绑定端口呢?

一般来说,如果要做成一个服务端的应用程序的话,是需要绑定固定端口的。

python3中的编码转换

  • 使用socket发送的是数据的二进制,需要将字符串转换成bytes

str.encode()

  • 使用socket接收的是数据的二进制,需要将bytes转换成字符

bytes.decode()

(0)

相关推荐

  • Python网络编程 —— 粘包问题及解决方法

    Python网络编程 —— 粘包问题及解决方法

  • 网络编程

    面向对象的使用 #使用面向对象解决datetime.tody()无法序列化的问题import jsonfrom datetime import datetime,date# print(date.to ...

  • php socket通信(tcp/udp)

    注意 1.在socket_bind的时候ip地址不能真回环地址如127.0.0.1 2.server.php后台跑起来的时候 nohup php server.php > /var/tmp/a. ...

  • day21 网络编程(下)

    版权声明:本博客转载自路飞学城Python全栈开发培训课件,仅用于学习之用,严禁用于商业用途. 欢迎访问路飞学城官网:https://www.luffycity.com/ 课程目标:学会网络编程开发的 ...

  • 第99天:TCP 编程

    网络连接与通信是我们学习任何编程语言都绕不过的知识点.Python 也不例外,本文就介绍因特网的核心协议 TCP ,以及如何用 Python 实现 TCP 的连接与通信. TCP 协议 TCP协议(T ...

  • 【汇总】Python网络编程框架有哪些?

    伴随着人工智能时代的到来,Python这门语言变得非常受欢迎,成为了很多开发人员的热捧,甚至还有不少小白.其他岗位就业人员想要转行学习Python,尤其是想要从事网络编程的人员,那么你知道Python ...

  • TCP/IP通信原理,Python网络编程详解!

    TCP/IP通信原理,Python网络编程详解!

  • Python网络编程基础及socket之TCP收发消息及文件

    网络编程必须了解的基本概念 MAC地址:是全球唯一标示的网络接口,每一个网卡接口.交换机接口.路由器接口的mac地址均不相同.mac地址是通信子网内部相互通信的标识,交换机根据mac地址区分用户.ma ...

  • 网络编程及前端面试题!Python入门

    当我们学习Python时,需要掌握的的知识有很多,除了有关Python的专业知识外,我们还需要学习网络编程.前端等知识,对此这篇文章为大家总结一下Python常见面试题之网络编程及前端的问题. 第一: ...

  • 迅为4412开发板Qt网络编程-UDP实现服务器和客户端

    UDP 协议是开放式,无连接,不可靠的传输层通信协议,但它收发数据的速度相对于 TCP 快很多,常用在传输音视频等数据量非常大的场合.udp 网络编程只需要使用一个类 QUdpSocket. 本实验中 ...

  • 【Python核心编程笔记】一、Python中一切皆对象

    Python中一切皆对象 本章节首先对比静态语言以及动态语言,然后介绍 python 中最底层也是面向对象最重要的几个概念-object.type和class之间的关系,以此来引出在python如何做 ...

  • Python游戏编程(Pygame)

    安装Pygame pip install pygame 1 C:\Users> pip install pygame Collecting pygame Downloading https:// ...

  • 老曹眼中的网络编程基础

    我们是幸运的,因为我们拥有网络.网络是一个神奇的东西,它改变了你和我的生活方式,改变了整个世界. 然而,网络的无标度和小世界特性使得它又是复杂的,无所不在,无所不能,以致于我们无法区分甚至无法描述. ...