一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Python網(wǎng)絡(luò)編程

 云深無際 2021-11-03

TCP 客戶端與服務(wù)器之間建立連接需要進(jìn)行三次握手 客戶端--->服務(wù)器  服務(wù)器--->客戶端  客戶端--->服務(wù)器,這樣做的好處是可以保證數(shù)據(jù)的完整缺點(diǎn)是慢.

  • UDP 是用戶數(shù)據(jù)報(bào)協(xié)議,傳輸模式是數(shù)據(jù)報(bào),

  • UDP 是無連接的協(xié)議,每個(gè)數(shù)據(jù)報(bào)都是一個(gè)獨(dú)立的信息,包括完整的源地址或目的地址,它在網(wǎng)絡(luò)上以任何可能的路徑傳往目的地,因此能否到達(dá)目的地,到達(dá)目的地的時(shí)間以及內(nèi)容的正確性都是不能被保證的。

  • UDP 是簡單不可靠的協(xié)議,它不提供可靠性,只是把數(shù)據(jù)包發(fā)送出去,并不保證能夠到達(dá)目的地。由于它不需要在客戶端和服務(wù)端之間建立連接,也沒有超時(shí)重發(fā)機(jī)制,所以傳輸速度很快。

UDP 不需要進(jìn)行三次握手,客戶端與服務(wù)器之間直接往對方臉上丟數(shù)據(jù)不管有沒有接到,優(yōu)點(diǎn)是快缺點(diǎn)是無法保證數(shù)據(jù)的完整.

UDP數(shù)據(jù)包一般包含512個(gè)字節(jié),當(dāng)大于512字節(jié)時(shí),可能會出現(xiàn)傳輸不穩(wěn)定的情況。

  • UDP每個(gè)發(fā)送的數(shù)據(jù)都含所有自身的報(bào)頭,不像TCP那樣是流式的數(shù)據(jù),所以不存在粘包現(xiàn)象。

  • udp的recvfrom是阻塞的,一個(gè)recvfrom(x)必須對唯一一個(gè)sendto(y),收完了x個(gè)字節(jié)的數(shù)據(jù)就算完成,若是y>x數(shù)據(jù)就丟失,這意味著udp根本不會粘包,但是會丟數(shù)據(jù),不可靠。

  • tcp 協(xié)議的數(shù)據(jù)不會丟,沒有收完的包下一次會接著收取上一次沒收完的數(shù)據(jù),本端總是在收到ack時(shí)才會清除緩沖區(qū)內(nèi)容。數(shù)據(jù)是可靠的,但是會粘包。

什么是socket:

這是為了實(shí)現(xiàn)以上的通信過程而建立成來的通信管道,其真實(shí)的代表是客戶端和服務(wù)器端的一個(gè)通信進(jìn)程,雙方進(jìn)程通過socket進(jìn)行通信,而通信的規(guī)則采用指定的協(xié)議。socket只是一種連接模式,不是協(xié)議,tcp,udp,簡單的說(雖然不準(zhǔn)確)是兩個(gè)最基本的協(xié)議,很多其它協(xié)議都是基于這兩個(gè)協(xié)議如,http就是基于tcp的,.用socket可以創(chuàng)建tcp連接,也可以創(chuàng)建udp連接,這意味著,用socket可以創(chuàng)建任何協(xié)議的連接,因?yàn)槠渌鼌f(xié)議都是基于此的。


UDP 傳輸?shù)牧鞒虉D


第一步導(dǎo)入網(wǎng)絡(luò)編程的庫,自帶的

import socket

接著就是要調(diào)用一個(gè)方法

socket.socket(AddressFamily, Type)

就解釋一下參數(shù),別的就不說了

  • Address Family:可以選擇 AF_INET(用于 Internet 進(jìn)程間通信) 或者 AF_UNIX(用于同一臺機(jī)器進(jìn)程間通信),實(shí)際工作中常用AF_INET

  • Type:套接字類型,可以是 SOCK_STREAM(流式套接字,主要用于 TCP 協(xié)議)或者 SOCK_DGRAM(數(shù)據(jù)報(bào)套接字,主要用于 UDP 協(xié)議)

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


import socket
# 創(chuàng)建udp socketudp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# ...# 使用套接字收/發(fā)數(shù)據(jù)
# 關(guān)閉socketudp_socket.close()

上面的代碼就是對于UDP的一次完整的調(diào)用

套接字使用流程 與 文件的使用流程很類似:

1.創(chuàng)建套接字

2.使用套接字收/發(fā)數(shù)據(jù)

3.關(guān)閉套接字

## 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

我直接給出一個(gè)實(shí)例,這是連接Dji教育無人機(jī)的一段代碼,很完整了已經(jīng)

sock.bind(locaddr)

使用bind公開一個(gè)端口,使得client可以方便連接

創(chuàng)建了一個(gè)無人機(jī)的地址,IP+端口


可以看到上面的tello_address是作為一個(gè)參數(shù)的函數(shù)使用.

# 發(fā)送數(shù)據(jù) send_addr = ('192.168.92.190', 7878) udp_socket.sendto(send_data.encode('GBK'), send_addr)

如果是字符集在兩個(gè)目標(biāo)上面不一樣,還可以去更改編碼模式

此時(shí)先下載一個(gè)調(diào)試工具,隨便下載

import socket

def main(): # 創(chuàng)建套接字 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 讀取輸入的數(shù)據(jù) send_data = input('請輸入要發(fā)送的數(shù)據(jù):')
# 發(fā)送數(shù)據(jù) send_addr = ('192.168.92.190', 7878) udp_socket.sendto(send_data.encode('GBK'), send_addr)
# 關(guān)閉 udp_socket.close()

if __name__ == '__main__': main()

http://www.zlmcu.com/document/tcp_debug_tools.html

我上面的軟件沒有調(diào)試出來,我換了一個(gè)軟件,調(diào)試成功

這個(gè)地方用wireshark看一下

選擇內(nèi)部的回環(huán)接口

設(shè)置這里看見是BSD

這個(gè)地方輸入三個(gè)1,a,b

位置信息

可以看到是這個(gè)地址確實(shí)發(fā)了三次信息

打開看看

數(shù)據(jù)31,長度1

可以用ifconfig看看自己的ip

import socket
def main():
# 創(chuàng)建套接字 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 綁定一個(gè)本地信息 localaddr = ("", 8080) udp_socket.bind(localaddr)
# 接收數(shù)據(jù) recv_data = udp_socket.recvfrom(1024)
# recv_data是一個(gè)元組(接收到的數(shù)據(jù), (發(fā)送方的IP, port)) recv_msg = recv_data[0] # 存儲接收到的數(shù)據(jù) send_addr = recv_data[1] # 存儲發(fā)送方的地址
# 打印收到的消息 # print(recv_data) print("%s:%s" % (str(send_addr), recv_msg.decode('GBK')))
# 關(guān)閉 udp_socket.close()
if __name__ == '__main__': main()

這段代碼是接收代碼,寫的很明白

udp端口綁定

  • 一個(gè)udp網(wǎng)絡(luò)程序,運(yùn)行時(shí)沒有綁定端口,系統(tǒng)會給它分配一個(gè)隨機(jī)的端口,如果再次運(yùn)行,端口可能發(fā)生變化

  • 一個(gè)udp網(wǎng)絡(luò)程序,也可以綁定信息(ip地址,端口號),如果綁定成功,那么操作系統(tǒng)用這個(gè)端口號來進(jìn)行區(qū)別收到的網(wǎng)絡(luò)數(shù)據(jù)是否是此進(jìn)程的

什么時(shí)候需要綁定端口呢?

一般來說,如果要做成一個(gè)服務(wù)端的應(yīng)用程序的話,是需要綁定固定端口的。

python3中的編碼轉(zhuǎn)換

  • 使用socket發(fā)送的是數(shù)據(jù)的二進(jìn)制,需要將字符串轉(zhuǎn)換成bytes

str.encode()
  • 使用socket接收的是數(shù)據(jù)的二進(jìn)制,需要將bytes轉(zhuǎn)換成字符

bytes.decode()

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    午夜福利92在线观看| 亚洲一区二区三区福利视频| 日本一本不卡免费视频| 日韩免费午夜福利视频| 日本妇女高清一区二区三区| 国产欧美日韩精品一区二区| 日韩国产亚洲欧美激情| 在线观看日韩欧美综合黄片| 91播色在线免费播放| 一区二区三区欧美高清| 欧美日韩一区二区三区色拉拉| 亚洲欧洲在线一区二区三区| 91精品国产品国语在线不卡| 日韩精品在线观看完整版| 久久精品国产亚洲av久按摩| 国产午夜精品亚洲精品国产| 在线精品首页中文字幕亚洲| 欧洲偷拍视频中文字幕| 日本亚洲欧美男人的天堂| 不卡视频免费一区二区三区| 人人妻在人人看人人澡| 国产日产欧美精品大秀| 99久久免费看国产精品| 亚洲成人精品免费在线观看| 国产乱淫av一区二区三区| 国产又黄又爽又粗视频在线| 丝袜视频日本成人午夜视频| 超薄肉色丝袜脚一区二区| 成人精品欧美一级乱黄| 美女极度色诱视频在线观看| 一区二区在线激情视频| 大香蕉大香蕉手机在线视频| 国内真实露脸偷拍视频| 亚洲第一区二区三区女厕偷拍| 久久经典一区二区三区| 亚洲一区二区三区av高清| 在线中文字幕亚洲欧美一区 | 欧美日韩国产黑人一区| 日韩精品成区中文字幕| 91偷拍与自偷拍精品| 国产又色又爽又黄又免费|