python--基於socket網路編程

来源:https://www.cnblogs.com/june-L/archive/2019/10/27/11749079.html
-Advertisement-
Play Games

Python 提供了兩個基本的 socket 模塊。 第一個是 Socket,它提供了標準的 BSD Sockets API。 第二個是 SocketServer, 它提供了伺服器中心類,可以簡化網路伺服器的開發。 1、Scoket類型 套接字格式: socket(family,type[,prot ...


Python 提供了兩個基本的 socket 模塊。

第一個是 Socket,它提供了標準的 BSD Sockets API。

第二個是 SocketServer, 它提供了伺服器中心類,可以簡化網路伺服器的開發。

1、Scoket類型

套接字格式:

socket(family,type[,protocal]) 使用給定的地址族、套接字類型、協議編號(預設為0)來創建套接字。

1.1、socket.AF_UNIX #只能夠用於單一的Unix系統進程間通信

1.2、socket.AF_INET #伺服器之間網路通信

1.3、socket.AF_INET6 #IPv6

1.4、socket.SOCK_STREAM #流式socket , for TCP

1.5、socket.SOCK_DGRAM #數據報式socket , for UDP

1.6、socket.SOCK_RAW #原始套接字,普通的套接字無法處理ICMP、IGMP等網路報文,而SOCK_RAW可以;其次,SOCK_RAW也可以處理特殊的IPv4報文;此外,利用原始套接字,可以通過IP_HDRINCL套接字選項由用戶構造IP頭。

1.7、socket.SOCK_SEQPACKET #可靠的連續數據包服務

1.8、創建TCP Socket: s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

1.9、創建UDP Socket: s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)


2、Socket 函數
註意點:
1)TCP發送數據時,已建立好TCP連接,所以不需要指定地址。UDP是面向無連接的,每次發送要指定是發給誰。
2)服務端與客戶端不能直接發送列表,元組,字典。需要字元串化repr(data)。


2.1、服務端socket函數

s.bind(address) #將套接字綁定到地址, 在AF_INET下,以元組(host,port)的形式表示地址.

s.listen(backlog) #開始監聽TCP傳入連接。backlog指定在拒絕連接之前,操作系統可以掛起的最大連接數量。該值至少為1,大部分應用程式設為5就可以了。

s.accept() #接受TCP連接並返回(conn,address),其中conn是新的套接字對象,可以用來接收和發送數據。address是連接客戶端的地址。

 

2.2、客戶端socket函數

s.connect(address) #連接到address處的套接字。一般address的格式為元組(hostname,port),如果連接出錯,返回socket.error錯誤。

s.connect_ex(adddress) #功能與connect(address)相同,但是成功返回0,失敗返回errno的值。


2.3、公共socket函數

s.recv(bufsize[,flag]) #接受TCP套接字的數據。數據以字元串形式返回,bufsize指定要接收的最大數據量。flag提供有關消息的其他信息,通常可以忽略。

s.send(string[,flag]) #發送TCP數據。將string中的數據發送到連接的套接字。返回值是要發送的位元組數量,該數量可能小於string的位元組大小。

s.sendall(string[,flag]) #完整發送TCP數據。將string中的數據發送到連接的套接字,但在返回之前會嘗試發送所有數據。成功返回None,失敗則拋出異常。

s.recvfrom(bufsize[.flag]) #接受UDP套接字的數據。與recv()類似,但返回值是(data,address)。其中data是包含接收數據的字元串,address是發送數據的套接字地址。

s.sendto(string[,flag],address) #發送UDP數據。將數據發送到套接字,address是形式為(ipaddr,port)的元組,指定遠程地址。返回值是發送的位元組數。

s.close() #關閉套接字。

s.getpeername() #返回連接套接字的遠程地址。返回值通常是元組(ipaddr,port)。

s.getsockname() #返回套接字自己的地址。通常是一個元組(ipaddr,port)

s.setsockopt(level,optname,value) #設置給定套接字選項的值。

s.getsockopt(level,optname[.buflen]) #返回套接字選項的值。

s.settimeout(timeout) #設置套接字操作的超時期,timeout是一個浮點數,單位是秒。值為None表示沒有超時期。一般,超時期應該在剛創建套接字時設置,因為它們可能用於連接的操作(如connect())

s.gettimeout() #返回當前超時期的值,單位是秒,如果沒有設置超時期,則返回None。

s.fileno() #返回套接字的文件描述符。

s.setblocking(flag) #如果flag為0,則將套接字設為非阻塞模式,否則將套接字設為阻塞模式(預設值)。非阻塞模式下,如果調用recv()沒有發現任何數據,或send()調用無法立即發送數據,那麼將引起socket.error異常。

s.makefile() #創建一個與該套接字相關連的文件

 

3、socket編程思路


3.1、TCP服務端:

1 創建套接字,綁定套接字到本地IP與埠

# socket.socket(socket.AF_INET,socket.SOCK_STREAM) , s.bind()

2 開始監聽連接 #s.listen()

3 進入迴圈,不斷接受客戶端的連接請求 #s.accept()

4 然後接收傳來的數據,併發送給對方數據 #s.recv() , s.sendall()

5 傳輸完畢後,關閉套接字 #s.close()


3.2、TCP客戶端:

1 創建套接字,連接遠端地址

# socket.socket(socket.AF_INET,socket.SOCK_STREAM) , s.connect()

2 連接後發送數據和接收數據 # s.sendall(), s.recv()

3 傳輸完畢後,關閉套接字 #s.close()


4、模擬聊天機器人實例

4.1、socket_server.py 服務端

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Socket伺服器端
"""
import socket

sk = socket.socket()
sk.bind(('127.0.0.1', 8080,))
sk.listen(5)
#接收客戶端請求
#連接,客戶端地址信息
while True:
conn, address = sk.accept() #accept()阻塞
conn.sendall(bytes('歡迎致電10086', encoding='utf-8'))
while True:
ret_byte = conn.recv(1024)
ret_str = str(ret_byte, encoding='utf-8')
if ret_str == 'q':
break
conn.sendall(bytes('工號10086回覆您:' + ret_str, encoding='utf-8'))

 

4.2、socket_client.py 客戶端

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
socket客戶端
"""
import socket

ck = socket.socket()
ck.connect(('127.0.0.1', 8080))
ret_byte = ck.recv(1024)
ret_str = str(ret_byte, encoding='utf-8')
print(ret_str)
while True:
inp = input("請輸入內容,按q退出 \n >>>")
if inp == 'q':
ck.sendall(bytes(inp, encoding='utf-8'))
break
else:
ck.sendall(bytes(inp, encoding='utf-8'))
ret_str = str(ck.recv(1024), encoding='utf-8')
print(ret_str)

ck.close()

 

5、基於socket實現文件上傳實例

5.1、ftp_server.py


#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
模擬發送文件的伺服器端
"""

import socket

sk = socket.socket()
sk.bind(('127.0.0.1', 8080,)) #綁定套接字到本地IP與埠
sk.listen(5) #開始監聽連接
#接收客戶端請求
#連接,客戶端地址信息
while True:
conn, address = sk.accept() # accept()阻塞
conn.sendall(bytes('歡迎訪問我的ftp', encoding='utf-8'))
#先接收文件大小,然後再接收文件
ret_size = str(conn.recv(1024), encoding='utf-8')
conn.sendall(bytes('start', encoding='utf-8')) #給客戶端發送一個確認信息,通知客戶端開始發送文件,解決數據粘包的問題。
total_size = int(ret_size) #文件總大小
has_recv = 0 #已經接收的文件大小
f = open('new.png', 'wb')
#接收文件內容,直到獲取完成
while True:
if total_size == has_recv:
break
data = conn.recv(1024)
f.write(data)
has_recv += len(data)
f.close()


 

5.2、ftp_client.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
模擬發送文件的客戶端
"""
import socket
import os

ck = socket.socket()
ck.connect(('127.0.0.1', 8080))
ret_byte = ck.recv(1024) #接收伺服器端返回的位元組數據
ret_str = str(ret_byte, encoding='utf-8') #將位元組數據轉換成字元串
print(ret_str)
#首先向伺服器發送文件的大小
file_size = os.stat('file1.png').st_size
ck.sendall(bytes(str(file_size), encoding='utf-8'))

ck.recv(1024) #接收一下伺服器端的確認信息,再開始發送文件,解決數據粘包引起的系統異常問題
#發送文件
with open('file1.png', 'rb') as f:
for line in f:
ck.sendall(line)
ck.close()

 

6、socketserver模塊實現併發操作

使用:
1、創建類,必須繼承socketserver.BaseRequestHandler
2、定義handle方法
3、server_forever

socketserver模塊實現併發操作實例:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
socketserver模塊實現併發操作
"""
import socketserver

class MyServer(socketserver.BaseRequestHandler):

def handle(self):
#self.request, self.client_address, self.server
conn = self.request
conn.sendall(bytes('歡迎致電10086', encoding='utf-8'))
while True:
ret_byte = conn.recv(1024)
ret_str = str(ret_byte, encoding='utf-8')
if ret_str == 'q':
break
conn.sendall(bytes('工號10086回覆您:' + ret_str, encoding='utf-8'))

if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), MyServer)
server.serve_forever()

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1 介紹 集合類可謂是學習必知、編程必用、面試必會的,而且集合的操作十分重要;本文主要講解如何合併集合類,如合併兩個數組,合併兩個List等。通過例子講解幾種不同的方法,有JDK原生的方法,還有使用第三庫的方法。 2 第三方庫 引入十分常用的優秀的第三方庫 和`Apache Commons pom. ...
  • A. Equalize Prices Again time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output You are both a s ...
  • 當我們開始開發項目部署運行時,項目規模不大,只是在一個JVM實例中運行,對同一資源的併發訪問用JDK自帶的鎖機制就可以解決資源同時訪問的問題。而隨著項目的不斷發展,單體應用已經無法滿足日益增長的訪問需求,我們開始考慮多台部署,提高接收客戶端的連接請求,提高項目的吞吐量。一臺變多台,其中不可避免的問題 ...
  • Hello,各位小伙伴大家好,我是小棧君,昨天也就是2019年10月26日,有幸在成都參加了由阿裡舉辦的“Dubbo社區開發者日”。 本次活動匯聚了各方面的大神歡聚一堂,主要是對現有微服務狀態下的技術的痛點和執行流程的分享和解析。近距離的接觸到技術大佬們,面對面的交流,讓人獲益良多。 所以小棧君這裡 ...
  • 1.什麼是rpc RPC全稱為Remote Procedure Call,翻譯過來為“遠程過程調用”。目前,主流的平臺中都支持各種遠程調用技術,以滿足分散式系統架構中不同的系統之間的遠程通信和相互調用。遠程調用的應用場景極其廣泛,實現的方式也各式各樣。 2.從通信協議的層面 基於HTTP協議的(例如 ...
  • 前言 本方法基於web2py框架,使用web2py的完整網站數據包創建簡單網站。 web2py 是一個為Python語言提供的全功能Web應用框架,旨在敏捷快速的開發Web應用,具有快速、安全以及可移植的資料庫驅動的應用,相容 Google App Engine。 (百度百科:https://bai ...
  • lambda表達式是什麼? lambda 表達式是 Python 中創建匿名函數的一個特殊語法. 我稱 lambda 語法本身為 lambda 表達式,而它返回的函數我稱之為 lambda 函數。或者稱為匿名函數。 Python 的 lambda 表達式允許在一行代碼中創建一個函數並傳遞。 看下麵的 ...
  • 相信用過 Spring Boot 的朋友們一定在啟動日誌中見過類似如下的內容,比如在啟動 Spring Boot 時,控制台預設會列印 Spring Boot Logo 以及版本信息,這是 Spring Boot 固定的還是可自定義的呢? . ____ _ __ _ _ /\\ / ___'_ __ ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...