python socket發(fā)送TCP數(shù)據(jù)方式
python socket發(fā)送TCP數(shù)據(jù)
用python寫socket發(fā)送 TCP的數(shù)據(jù)
import socket import time
#客戶端發(fā)送500個包 創(chuàng)建socket、連接、發(fā)送、關閉
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #綁定端口,發(fā)送數(shù)據(jù)時會從綁定的端口發(fā)送,不會再生成隨機端口 #tcp_socket.bind(("*.*.*.*", 8001)) tcp_socket.connect(("127.0.0.1", 8000)) n = 0 while(n<500): ? ? send_data = str(n) ? ? tcp_socket.send(send_data.encode("utf-8")) ? ? time.sleep() ? ? n=n+1 tcp_socket.close()
#接收端接收500個包 創(chuàng)建socket、綁定端口、監(jiān)聽端口、接收連接請求、接收數(shù)據(jù)、關閉
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_socket.bind(("192.168.1.128(本機私網IP)", 8000)) tcp_socket.listen() client_scoket,client_addr = tcp_socket.accept() timestamps = [] n = 0 while(n<500): ? ? recv_data = client_scoket.recv(1024) ? ? print(recv_data.decode('utf-8')) ? ? timestamps.append(time.perf_counter()) ?# 記錄時間戳 ? ? n = n+1 client_scoket.close() tcp_socket.close()
Python Socket(TCP和UDP)
IP協(xié)議負責把數(shù)據(jù)從一臺計算機通過網絡發(fā)送到另一臺計算機。數(shù)據(jù)被分割為一塊一塊,然后通過IP包發(fā)送出去,IP包的特點是按塊發(fā)送,途徑多個路由,但是不保證可以到達,也不保證順序到達。
TCP協(xié)議建立在IP協(xié)議之上,負責在兩臺計算機之間建立可靠連接,保證數(shù)據(jù)包順序到達,建立連接,對每個IP包編號,確保順序收到,如果包丟了,就自動重發(fā)。
TCP(比較可靠的傳輸)
TCP連接是可靠連接,如果傳輸比較重要,確保對方收到,可以用TCP。建立TCP連接時,主動發(fā)起連接的是客戶端(client),而被動響應連接的是服務器(server)。
下邊例子實現(xiàn):客戶端向服務端發(fā)送數(shù)據(jù),服務端接收此數(shù)據(jù),進行計算,將該結果返回客戶端。
服務端
利用docker容器運行服務端
起容器時應該將容器的12312端口(該端口號為服務端程序中暴露的端口號)映射到主機的端口
使用鏡像test:v1啟動一個容器,在容器內執(zhí)行/bin/bash命令,將容器的12312端口映射到主機的12312端口,主機的目錄/data映射到容器的/data
docker run -it -p 12312:12312 -v /test:/test test:v1 /bin/bash
程序如下:
import socketimport numpy as npimport time s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)host = '0.0.0.0' # ip地址port = 12313 # 端口號s.bind((host, port))s.listen(5)print('Waiting for connection...')sock, addr = s.accept()print('Connection successful:', addr)sock.send(b'Send data please')while True: client_data = sock.recv(400000) time.sleep(1) if not client_data: break get_data = np.fromstring(client_data, np.float32) get_data = np.array(get_data).reshape(1,2,3,4) print(get_data) result = get_data cilent_result = result.tostring() sock.send(cilent_result)sock.close()print('Connection closed!')
上述程序是進行一次傳輸之后自動結束運行,如果服務端可循環(huán)接收數(shù)據(jù),可手動控制停止,可用下述方法。
import socket import numpy as np import time s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = '0.0.0.0' # ip地址 port = 12313 # 端口號 s.bind((host, port)) s.listen(5) print('Waiting for connection...') sock, addr = s.accept() print('Connection successful:', addr) sock.send(b'Send data please') while True: client_data = sock.recv(400000) time.sleep(1) if not client_data: break get_data = np.fromstring(client_data, np.float32) get_data = np.array(get_data).reshape(1,2,3,4) print(get_data) result = get_data cilent_result = result.tostring() sock.send(cilent_result) sock.close() print('Connection closed!')
客戶端
客戶端容器不用指定端口,正常起容器
程序如下:
import socket import numpy as np data = np.ones((1,2, 3, 4),np.float32) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('123.123.0.1', 12313)) # 服務端IP地址, 該地址為服務端的IP地址 print(s.recv(1024).decode('utf-8')) # 端口號,與服務端暴露的端口號一致 client_data = data.tostring() s.send(client_data) serve_result = s.recv(40000) result = np.fromstring(serve_result, np.float32) result = np.array(result).reshape(1,2,3,4) print(result) s.close()
UDP(不要求可靠到達傳輸)
UDP傳輸不需要建立連接,只需要知道對方的IP地址和端口號即可發(fā)送。但是對方能不能收到就不確定了。
當進行一個不要求可靠到達的數(shù)據(jù)傳輸,就可以使用UDP協(xié)議,該傳輸方式不可靠但是速度比較快。
以下程序UDP實現(xiàn):服務端收到客戶端的信息,進行計算,將結果返回客戶端。客戶端退出,而服務端需要手動退出。(下述程序需在同一主機上用兩個終端運行)
服務端
程序如下:
import socket import numpy as np import time s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) host = '127.0.0.1' port = 9999 s.bind((host, port)) while True: data, addr = s.recvfrom(4000) if not data: break get_data = np.fromstring(data, np.float32) get_data = np.array(get_data).reshape(1,2,3,4) print(get_data) result = get_data client_result = result.tostring() s.sendto(client_result, addr)
客戶端
import socket import numpy as np s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) host = '127.0.0.1' port = 9999 data = np.ones((1,2, 3, 4),np.float32) client_data = data.tostring() s.sendto(client_data, (host, port)) serve_result, addr = s.recvfrom(40000) result = np.fromstring(serve_result, np.float32) result = np.array(result).reshape(1,2,3,4) print(result) s.close()
注:IP地址設置為0.0.0.0,并不是一個真實的IP地址,表示本地中所有的IPV4地址,監(jiān)聽0.0.0.0的端口,就是監(jiān)聽本機中所有的IP端口
IP地址設置為127.0.0.1,表示本機地址,如果綁定到這個地址,客戶端必須同時在本機運行才能連接,外部的計算機無法連接進來。一般會通過ping 127.0.0.1來測試某臺機器上的網絡設備是否正常。
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Django 如何從request中獲取前端數(shù)據(jù)
這篇文章主要介紹了Django從request中獲取前端數(shù)據(jù)的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04Python數(shù)據(jù)分析pandas模塊用法實例詳解
這篇文章主要介紹了Python數(shù)據(jù)分析pandas模塊用法,結合實例形式分析了pandas模塊對象創(chuàng)建、數(shù)值運算等相關操作技巧與注意事項,需要的朋友可以參考下2019-11-11Python3從零開始搭建一個語音對話機器人的實現(xiàn)
這篇文章主要介紹了Python3從零開始搭建一個語音對話機器人的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-08-08使用django-suit為django 1.7 admin后臺添加模板
前面我們介紹了Django-grappelli給admin添加模板,可是使用中發(fā)現(xiàn)inline有點問題,所以就換了今天我們要談的Django-suit,貌似要稍微好一些2014-11-11