成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Python中的Socket編程,全掌握!

開發 前端
Sockets 是組成當今網絡的各種通信協議,這些協議使得在兩個不同的程序或設備之間傳輸信息成為可能。例如,當我們打開瀏覽器時,我們作為客戶機就會創建與服務器的連接以傳輸信息。

在如今的互聯網當中,Socket 協議是最重要的基礎之一。本文涵蓋了在 Python 中處理 Socket 編程的所有領域。

圖片

為什么使用 Sockets

Sockets 是組成當今網絡的各種通信協議,這些協議使得在兩個不同的程序或設備之間傳輸信息成為可能。例如,當我們打開瀏覽器時,我們作為客戶機就會創建與服務器的連接以傳輸信息。

在深入研究這個通信原理之前,讓我們先弄清楚 Sockets 到底是什么。

什么是 Sockets

一般來說,Socket 是為發送和接收數據而構建的內部應用協議。單個網絡將有兩個 Sockets,每個 Sockets 用于通信設備或程序,這些 Sockets 是IP地址和端口的組合。根據使用的端口號,單個設備可以有“n”個 Sockets,不同的端口可用于不同類型的協議。

下圖展示了一些常見端口號和相關協議的信息:

協議

端口號

Python 庫

應用

HTTP

80

httplib,urllib,requests

網頁,網站

FTP

20

ftplib

文件傳輸

NNTP

119

nttplib

新聞傳輸

SMTP

25

smtplib

發送郵件

Telnet

23

telnetlib

命令行

POP3

110

poplib

接收郵件

Gopher

70

gopherlib

文檔傳輸

現在我們已經了解了 Sockets 的概念,現在讓我們來看看 Python 的 Socket 模塊

如何在 Python 中實現 Socket 編程

要在 Python 中實現 Socket 編程,需要導入 socket 模塊。

該模塊的一些重要方法如下:

方法

描述

socket.socket()

用于創建 socket(服務器端和客戶端都需要創建)

socket.accept()

用于接受連接。它返回一對值(conn,address),其中conn是用于發送或接收數據的新 socket 對象,address是連接另一端的 socket 地址

socket.bind()

用于綁定到指定為參數的地址

socket.close()

用于關閉 socket

socket.connect()

用于連接到指定為參數的遠程地址

socket.listen()

使服務器能夠接受連接

現在我們已經了解了 socket 模塊的重要性,接下來讓我們看看如何在 Python 中建服務器和客戶機。

什么是服務器

服務器或者是一個程序、一臺計算機,或者是一臺專門用于管理網絡資源的設備。服務器可以位于同一設備或計算機上,也可以本地連接到其他設備和計算機,甚至可以遠程連接。有各種類型的服務器,如數據庫服務器、網絡服務器、打印服務器等。

服務器通常使用socket.socket(),socket.bind(),socket.listen()等來建立連接并綁定到客戶端,現在讓我們編寫一個程序來創建服務器。

import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(),1234))
#port number can be anything between 0-65535(we usually specify non-previleged ports which are > 1023)
s.listen(5)

while True:
clt,adr=s.accept()
print(f"Connection to {adr}established")
#f string is literal string prefixed with f which
#contains python expressions inside braces
clt.send(bytes("Socket Programming in Python","utf-8 ")) #to send info to clientsocket

創建 socket 的第一個必要條件是導入相關模塊。之后是使用socket.socket()方法創建服務器端 socket。


AF_INET 是指來自 Internet 的地址,它需要一對(主機、端口),其中主機可以是某個特定網站的 URL 或其地址,端口號為整數。SOCK_STREAM 用于創建 TCP 協議。

bind()?方法接受兩個參數作為元組(主機、端口)。這里需要注意的是最好使用4位的端口號,因為較低的端口號通常被占用或者是系統預留的。listen()方法允許服務器接受連接,5是同時接受的多個連接的隊列。此處可以指定的最小值為0,如果未指定參數,則采用默認的合適參數。

while?循環允許永遠接受連接,clt和adr?是客戶端對象和地址,print?語句只是打印出客戶端 socket 的地址和端口號,最后,clt.send用于以字節為單位發送數據。

現在我們的服務器已經設置好了,讓我們繼續向客戶機前進。

什么是客戶端

客戶端是從服務器接收信息或服務的計算機或軟件。在客戶端-服務器模型中,客戶端從服務器請求服務。最好的例子是 Google Chrome、Firefox 等 Web 瀏覽器,這些 Web 瀏覽器根據用戶的指示請求 Web 服務器提供所需的網頁和服務。其他示例包括在線游戲、在線聊天等。

現在,讓我們看看如何用 Python 編程語言編寫客戶端程序:

import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 2346))
msg=s.recv(1024)
print(msg.decode("utf-8"))

首先依然是導入 socket 模塊,然后像創建服務器時那樣創建套接字。接著要在客戶端服務器之間創建連接,需要通過指定(host,port)使用 connect()方法。

注意:當客戶端和服務器位于同一臺計算機上時,需要使用gethostname。(LAN–localip/WAN–publicip)

在這里,客戶端希望從服務器接收一些信息,為此,我們需要使用recv()?方法,信息存儲在另一個變量msg中。需要注意的是正在傳遞的信息將以字節為單位,在上述程序的客戶端中,一次傳輸最多可以接收1024字節(緩沖區大小)。根據傳輸的信息量,可以將其指定為任意數量。

最后,再解碼并打印正在傳輸的消息。

現在我們已經了解了如何創建客戶端-服務器程序,接下來讓我們看看它們需要如何執行。

客戶端服務器交互

要執行這些程序,需要打開命令程序,進入創建客戶端和服務器程序的文件夾,然后鍵入:

py server.py #這里,server.py 是服務器的文件名

不出意外服務器開始運行

圖片

要執行客戶端,需要打開另一個cmd窗口,然后鍵入:

py  client.py

圖片

下面讓我們將緩沖區大小減少到7,來看看相同的程序會怎么樣

圖片

如圖所示,傳輸7個字節后,連接終止。

其實這是一個問題,因為我們尚未收到完整的信息,但是連接卻提前關閉了,下面讓我們來解決這個問題。

多重通信

為了在客戶端收到完整信息之前繼續連接,我們可以使用while循環

import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 2346))
while True:
msg=s.recv(7)
print(msg.decode("utf-8"))

如此修改之后,每次傳輸將以7個字節接收完整消息。

但這又引來了另一個問題,連接永遠不會終止,你永遠不知道什么時候會終止。此外,如果我們實際上不知道客戶端將從服務器接收到的消息或信息有多大,該怎么辦。在這種情況下,我們需要繼續完善代碼

complete_info=''
while True:
msg = s.recv(7)
if len(msg)<=0:
break
complete_info += msg.decode("utf-8")
print(complete_info)

在服務器端,使用close()方法,如下所示:

clt.close()

輸出如下:

圖片

程序會檢查信息的大小,并將其打印到一次兩個字節的緩沖區中,然后在完成連接后關閉連接。

傳輸 Python 對象

目前為止我們僅僅掌握了傳遞字符串的方法,但是,Python 中的 Socket 編程也允許我們傳輸 Python 對象。這些對象可以是集合、元組、字典等。要實現這一點,需要用到 Python 的 pickle 模塊。

Python pickle模塊

當我們實際序列化或反序列化 Python 中的對象時,就會使用到 Python pickle 模塊。讓我們看一個小例子

import pickle

mylist=[1,2,'abc']
mymsg = pickle.dumps(mylist)
print(mymsg)

Output:

b’x80x03]qx00(Kx01Kx02Xx03x00x00x00abcqx01e.’

在上面的程序中,mylist?是使用pickle模塊的dumps()?函數序列化的。還要注意,輸出以b開頭,表示它已轉換為字節。在 socket 編程中,可以實現此模塊以在客戶端和服務器之間傳輸 python 對象。

如何使用 pickle 模塊傳輸 Python 對象

當我們將 pickle 與 socket 一起使用時,完全可以通過網絡傳輸任何內容。

先來看看服務端代碼

Server-Side:

import socket
import pickle

a=10
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 2133)) #binding tuple
s.listen(5)
while True:
clt , adr = s.accept()
print(f"Connection to {adr}established")

m={1:"Client", 2:"Server"}
mymsg = pickle.dumps(m) #the msg we want to print later
mymsg = {len(mymsg):{a}}"utf-8") + mymsg
clt.send(mymsg)

這里,m?是一個字典,它基本上是一個需要從服務器發送到客戶端的 Python 對象。這是通過首先使用dumps()序列化對象,然后將其轉換為字節來完成的。

現在,讓我們記下客戶端:

Client-Side:

import socket
import pickle
a=10
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 2133))

while True:
complete_info = b''
rec_msg = True
while True:
mymsg = s.recv(10)
if rec_msg:
print(f"The length of message = {mymsg[:a]}")
x = int (mymsg[:a ] )
rec_msg = False
complete_info += mymsg
if len(complete_info)-a == x:
print("Recieved the complete info")
print(complete_info[a:])
m = pickle.loads(complete_info[a:])
print(m)
rec_msg = True
complete_info = b''
print(complete_info)

第一個while循環將幫助我們跟蹤完整的消息(complete_info)以及正在使用緩沖區接收的消息(rec_msg)。

然后,在接收消息時,我們所做的就是打印每一位消息,并將其放在大小為10的緩沖區中接收。此大小可以是任何大小,具體取決于個人選擇。

然后如果收到的消息等于完整消息,我們只會將消息打印為收到的完整信息,然后使用loads()反序列化消息。

輸出如下:

? 圖片 ?

責任編輯:武曉燕 來源: 蘿卜大雜燴
相關推薦

2024-04-23 13:36:00

2023-08-04 09:43:16

Socket編程Python

2010-03-03 16:19:29

Python Sock

2011-06-13 16:51:19

Qt Socket

2015-03-10 13:43:00

JavaSocket編程編程

2024-02-26 00:00:00

GoSocket編程

2013-09-22 11:03:20

SocketSocket編程

2016-11-04 21:37:16

PythonSocket

2012-03-19 11:41:30

JavaSocket

2011-06-20 13:43:08

Qt Socket 線程

2021-01-08 15:14:16

Python循環for循環

2010-03-17 13:46:55

Python sock

2023-10-26 15:49:53

Go日志

2013-03-26 12:46:23

Android開發So

2013-03-27 13:26:04

Android開發Socket

2020-10-15 19:10:05

LinuxAPI函數

2010-03-19 14:28:58

Java Socket

2023-02-16 09:55:24

對象編程OOP

2009-06-11 10:00:05

Java Socket

2010-02-24 13:56:27

Python編程語言
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产在线精品一区二区 | 日日碰狠狠躁久久躁96avv | 久久成人国产精品 | 一区二区三区视频在线免费观看 | 一区二区视频 | 亚洲精品视频观看 | 午夜视频网站 | 日韩成人精品一区二区三区 | 91视频播放| 91看片网 | 日本超碰| 激情一区二区三区 | 亚洲女人天堂成人av在线 | 欧美日韩一区在线 | 久久综合av| jdav视频在线观看免费 | 黑人巨大精品欧美一区二区免费 | 亚洲精选一区 | 日韩成人性视频 | 日韩欧美在线观看视频网站 | 天天拍天天操 | 午夜欧美日韩 | 久久黄色网 | 色眯眯视频在线观看 | av香港经典三级级 在线 | 99久久免费精品视频 | 国产在视频一区二区三区吞精 | 欧洲一级毛片 | 成人免费小视频 | 国产91丝袜 | 久久机热 | 中文字幕高清视频 | 一区二区三区视频在线 | 亚洲网站在线播放 | 久久久久一区二区三区 | 国产成人在线视频 | 日韩精品久久久久 | 在线成人福利 | 精品久久99| 一级毛片在线视频 | 黄色网一级片 |