Pythonソケットプログラミングの詳細な説明と実践ガイド

王林
リリース: 2023-04-22 17:04:08
転載
2800 人が閲覧しました

今日のインターネットでは、ソケット プロトコルは最も重要な基盤の 1 つです。この記事では、Python でのソケット プログラミングの作業に関するすべての領域を説明します。

Pythonソケットプログラミングの詳細な説明と実践ガイド

ソケットを使用する理由

ソケットは、今日のネットワークを構成するさまざまな通信プロトコルであり、2 つの異なるプログラムまたはデバイス間での情報の送信を可能にします。可能になる。たとえば、ブラウザを開くと、クライアントとしてサーバーへの接続が作成され、情報が転送されます。

この通信原理を詳しく説明する前に、まずソケットとは何かを明確にしましょう。

ソケットとは

一般的に、ソケットはデータの送受信のために構築された内部アプリケーション プロトコルです。 1 つのネットワークには、通信するデバイスまたはプログラムごとに 1 つずつ、合計 2 つのソケットがあり、これらのソケットは IP アドレスとポートの組み合わせです。使用されるポート番号に応じて、1 つのデバイスが「n」個のソケットを持つことができ、異なるタイプのプロトコルに異なるポートを使用できます。

次の図は、いくつかの一般的なポート番号と関連プロトコル情報を示しています:

##アプリケーションHTTP#80httplib、urllib、リクエストWeb ページ、Web サイトFTP20NNTP##nttplib# #23##110

プロトコル

ポート番号

##Python ライブラリ









##ftplib


ファイル転送


#119



#ニュース転送


#SMTP

25

##smtplib


電子メールを送信



Telnet


##telnetlib


コマンド ライン


POP3


##poplib

メールを受信


ゴーファー


70

gopherlib

文書転送

ソケットの概念を理解したところで、Python のソケット モジュールを見てみましょう

Python でソケット プログラミングを実装する方法

Python でソケット プログラミングを実装するには、次のものが必要です。ソケットモジュールをインポートします。

#このモジュールのいくつかの重要なメソッドは次のとおりです:

#説明##socket.socket()socket.accept()##socket.bind()#パラメータとして指定されたアドレスにバインドするために使用されますsocket.close() ソケットを閉じるために使用されます
##メソッド




#ソケットの作成に使用されます (サーバーとクライアントの両方を作成する必要があります)


は接続を受け入れるために使用されます。これは値のペア (conn, address) を返します。conn はデータの送受信に使用される新しいソケット オブジェクトで、address は接続のもう一方の端のソケット アドレスです。





#socket.connect()


パラメータとして指定されたリモート アドレスに接続するために使用されます


socket.listen()


サーバーが接続を受け入れられるようにする

#

ソケット モジュールの重要性を理解したところで、Python でサーバーとクライアントを構築する方法を見てみましょう。

サーバーとは

サーバーとは、ネットワーク リソースの管理に特に使用されるプログラム、コンピューター、またはデバイスのいずれかです。サーバーは、同じデバイスまたはコンピュータ上に配置することも、他のデバイスやコンピュータにローカルに接続することも、リモートに配置することもできます。サーバーにはデータベースサーバー、Webサーバー、プリントサーバーなどさまざまな種類があります。

サーバーは通常、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() メソッドを使用してサーバー側ソケットを作成します。


AF_INET はインターネットからのアドレスを指します。これにはペア (ホスト、ポート) が必要です。ホストは URL または特定の Web サイトのアドレスです。 , ポート番号は整数です。 SOCK_STREAM は、TCP プロトコルの作成に使用されます。

bind() メソッドは、2 つのパラメータをタプル (ホスト、ポート) として受け入れます。ここで、小さいポート番号は通常、システムによって占有または予約されているため、4 桁のポート番号を使用するのが最善であることに注意してください。 listen() メソッドを使用すると、サーバーは接続を受け入れることができます。5 は同時に受け入れられる複数の接続のキューです。ここで指定できる最小値は 0 で、パラメーターが指定されていない場合は、デフォルトの適切なパラメーターが使用されます。

while ループでは接続を永久に受け入れることができます。clt と adr はクライアント オブジェクトとアドレスです。print ステートメントはクライアント ソケットのアドレスとポート番号を出力するだけです。最後に clt.send を使用してsend bytes データをユニットに送信します。

サーバーのセットアップが完了したので、クライアントに進みましょう。

クライアントとは

クライアントは、サーバーから情報やサービスを受信するコンピューターまたはソフトウェアです。クライアント/サーバー モデルでは、クライアントはサーバーにサービスを要求します。最良の例は、Google Chrome、Firefox などの Web ブラウザです。これらの 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"))
ログイン後にコピー

まず、引き続きソケット モジュールをインポートし、サーバーの作成時と同様にソケットを作成します。 。次に、クライアントとサーバー間の接続を作成するには、(ホスト、ポート) を指定して connect() メソッドを使用する必要があります。

注: クライアントとサーバーが同じコンピュータ上にある場合は、gethostname を使用する必要があります。 (LAN – localip/WAN – publicip)

ここで、クライアントはサーバーから何らかの情報を受け取りたいと考えています。このためには、recv() メソッドを使用する必要があります。情報は別の変数に保存されます。メッセージ 。転送される情報はバイト単位であることに注意することが重要です。上記のプログラムのクライアントでは、1 回の転送で最大 1024 バイト (バッファ サイズ) を受信できます。転送される情報の量に応じて、任意の数値を指定できます。

最後に、送信されているメッセージをデコードして出力します。

クライアント/サーバー プログラムの作成方法を説明したので、次にそれらを実行する必要がある方法を見てみましょう。

クライアントとサーバーの対話

これらのプログラムを実行するには、コマンド プログラムを開き、クライアント プログラムとサーバー プログラムが作成されたフォルダーに移動して、次のように入力する必要があります。

py server.py #这里,server.py 是服务器的文件名
ログイン後にコピー

当然のことですが、サーバーが実行を開始します

Pythonソケットプログラミングの詳細な説明と実践ガイド

クライアントを実行するには、別の cmd ウィンドウを開いて次のように入力する必要があります:

pyclient.py
ログイン後にコピー

Pythonソケットプログラミングの詳細な説明と実践ガイド

# 以下のバッファ サイズを 7 に減らして、同じプログラムがどのようになるかを見てみましょう。

Pythonソケットプログラミングの詳細な説明と実践ガイド

図に示すように、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 对象

目前为止我们仅仅掌握了传递字符串的方法,但是,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()反序列化消息。

输出如下:

Pythonソケットプログラミングの詳細な説明と実践ガイド

以上がPythonソケットプログラミングの詳細な説明と実践ガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:51cto.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!