検索
ホームページバックエンド開発Python チュートリアルPythonソケットプログラミングの予備調査

ソケット プログラミングの手順

サーバーはソケットを作成し、アドレスとポートをバインドし、接続が確立されると、accept 関数を通じて受信接続を受信します。

クライアントはソケットも作成します。リモート アドレスとポートをバインドし、接続を確立してデータを送信します。

サーバーソケット

以下は、サンプルコードを通して詳細に説明します。サーバー socker_server.py

import socket
import sys

HOST = "127.0.0.1"               
PORT = 10000              
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
                              socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
    af, socktype, proto, canonname, sa = res
    try:
        s = socket.socket(af, socktype, proto)
    except socket.error as msg:
        s = None
        continue
    try:
        s.bind(sa)
        s.listen(5)
    except socket.error as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print 'could not open socket'
    sys.exit(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
    data = conn.recv(1024)
    if not data: break
    conn.send(data)
conn.close()

まず、socket.getaddrinnfo 関数を通じて、ホスト/ポートを 5 つのタプルを含むシーケンスに変換します。この 5 タプルには、ソケット接続を作成するために必要なパラメータがすべて含まれています。返される 5 タプルは (family、sockettype、proto、canonname、sockaddr)

ファミリー アドレス クラスターであり、socket() 関数の最初のパラメーターとして使用されます。主に次のようなものがあります:

socket.AF_UNIX は単一マシン上のプロセスとの通信に使用されます。
socket.AF_INET はサーバーとの通信に使用されます。
socket.AF_INET6 は IPv6 をサポートします
sockettype ソケットタイプ、socket() 関数の 2 番目のパラメータとして使用されます。一般的に使用されるものは、

TCP プロトコルに使用されるデフォルトの socket.SOCK_STREAM
UDP プロトコルに使用される
socket.SOCK_DGRAM です。使用されるsocket()関数の3番目のパラメータ。 getaddrinnfo 関数は、アドレス形式とソケット タイプに基づいて、適切なプロトコル

canonname と標準化されたホスト名を返します。

sockaddr はソケットアドレスを記述します。これは主にbind()関数とconnect()関数に使用されるタプルです

次に、ソケットオブジェクトを作成し、getaddrinnfo関数によって返されるaf、sockettype、protoを渡します。

s = socket.socket(af, socktype, proto)

次にソケットアドレスをバインドします

s.bind(sa)

リスニングモードを有効化します

s.listen(5)

listen 関数は、ソケットに接続されている接続をリッスンします。このパラメーターは、システムが接続を拒否する前に一時停止できる接続キューの最大数が 5 であることを示します。 。これらの接続はまだ受け入れられていません。数量を無限にすることはできません。通常は 5 が指定されます。

接続をリッスンしたら、accept 関数を呼び出して接続を受信します

conn, addr = s.accept()

accept 関数はタプルを返し、conn はデータの送受信に使用される新しいソケット オブジェクトです。 addr は相手側のソケットアドレスを表します。

次に、conn オブジェクトを使用してデータを送受信できます

 data = conn.recv(1024) # 接收数据, 这里指定一次最多接收的字符数量为1024
 conn.send(data) # 发送数据

ここでは、接続ソケットを受信すると実行を停止するため、接続をループしたい場合は、accept 関数を無限ループに入れます。

クライアント ソケット

クライアント ソケットのプログラミングは、connect を通じてサーバーとの接続を確立した後、相互に通信できるようになります。 socket_client.pyは以下の通りです

for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM):
    af, socktype, proto, canonname, sa = res
    try:
        s = socket.socket(af, socktype, proto)
    except socket.error as msg:
        s = None
        continue
    try:
        s.connect(sa)
    except socket.error as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print 'could not open socket'
    sys.exit(1)
s.sendall('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)

上記は主にTCPストリームデータのソケットプログラミングです。 UDP プロトコル データの場合、処理は少し異なります。たとえば、UDP パケットを送受信するための処理関数は次のとおりです。

socket.sendto(string, flags, address)
socket.recvfrom(bufsize[, flags]) #返回(string, address),string是返回的数据,address是发送方的socket地址

SocketServer モジュール

Python のネットワーク プログラミングでは、ソケット モジュールに加えて、SocketServer モジュールも提供されます。このモジュールは主にソケット モジュールをカプセル化し、ソケット モジュールの作成をバインドします。ソケット オブジェクトの設定、接続、受信、送信、および終了はすべて内部にカプセル化されているため、ネットワーク サービスのプログラミングが大幅に簡素化されます。

このモジュールは、対応するソケット ストリームを作成するための次の 2 つの主要なネットワーク サービス クラスを提供します

TCPServer は TCP プロトコルのソケット ストリームを作成します

UDPServer は UDP プロトコルのソケット ストリームを作成します

ソケット ストリーム オブジェクトに加えて、 、リクエスト処理クラスも必要です。 SocketServer モジュールは、BaseRequestHandler とその派生クラス StreamRequestHandler および DatagramRequestHandler を含むリクエスト処理クラスを提供します。したがって、これら 3 つのクラスのいずれかを継承して、受信したリクエストを処理するためにこの関数を使用してハンドル関数をオーバーライドするだけです。サーバー側のコード例を見てみましょう

import SocketServer

class MyTCPHandler(SocketServer.StreamRequestHandler):
   """创建请求处理类,重写handle方法。此外也可以重写setup()和finish()来做一些请求处理前和处理后的一些工作"""
    def handle(self):
        # self.request is the TCP socket connected to the client
        self.data = self.request.recv(1024).strip()
        print "{} wrote:".format(self.client_address[0])
        print self.data
        # just send back the same data, but upper-cased
        self.request.sendall(self.data.upper())

if __name__ == "__main__":
    HOST, PORT = "localhost", 10000

    server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)

    # Activate the server; this will keep running until you
    # interrupt the program with Ctrl-C
    # server.shutdown()
    server.serve_forever()  # 一直循环接收请求
    # server.handle_request() # 只处理一次请求就退出

看着是不是代码简单了很多,而且SocketServer模块内部使用了多路复用IO技术,可以实现更好的连接性能。看serve_forever函数的源代码用到了select模块。通过传入socket对象调用select.select()来监听socket对象的文件描述符,一旦发现socket对象就绪,就通知应用程序进行相应的读写操作。源代码如下:

def serve_forever(self, poll_interval=0.5):
        """Handle one request at a time until shutdown.

        Polls for shutdown every poll_interval seconds. Ignores
        self.timeout. If you need to do periodic tasks, do them in
        another thread.
        """
        self.__is_shut_down.clear()
        try:
            while not self.__shutdown_request:
                # XXX: Consider using another file descriptor or
                # connecting to the socket to wake this up instead of
                # polling. Polling reduces our responsiveness to a
                # shutdown request and wastes cpu at all other times.
                r, w, e = _eintr_retry(select.select, [self], [], [],
                                       poll_interval)
                if self in r:
                    self._handle_request_noblock()
        finally:
            self.__shutdown_request = False
            self.__is_shut_down.set()

即使使用了select技术,TCPServer,UDPServer处理请求仍然是同步的,意味着一个请求处理完,才能处理下一个请求。但SocketServer模块提供了另外2个类用来支持异步的模式。

ForkingMixIn 利用多进程实现异步

ThreadingMixIn 利用多线程实现异步

看名字就知道使用了mixin模式。而mixin模式可以通过多继承来实现,所以通过对网络服务类进行多继承的方式就可以实现异步模式

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass

针对ThreadindMixIn,实现异步的原理也就是在内部对每个请求创建一个线程来处理。看源码

def process_request(self, request, client_address):
        """Start a new thread to process the request."""
        t = threading.Thread(target = self.process_request_thread,
                             args = (request, client_address))
        t.daemon = self.daemon_threads
        t.start()

下面提供一个异步模式的示例

import socket
import threading
import SocketServer

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):

    def handle(self):
        data = self.request.recv(1024)
        cur_thread = threading.current_thread()
        response = "{}: {}".format(cur_thread.name, data)
        self.request.sendall(response)

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass

def client(ip, port, message):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((ip, port))
    try:
        sock.sendall(message)
        response = sock.recv(1024)
        print "Received: {}".format(response)
    finally:
        sock.close()

if __name__ == "__main__":
    # Port 0 means to select an arbitrary unused port
    HOST, PORT = "localhost", 0

    server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
    ip, port = server.server_address

    # Start a thread with the server -- that thread will then start one
    # more thread for each request
    server_thread = threading.Thread(target=server.serve_forever)
    # Exit the server thread when the main thread terminates
    server_thread.daemon = True
    server_thread.start()
    print "Server loop running in thread:", server_thread.name

    client(ip, port, "Hello World 1")
    client(ip, port, "Hello World 2")
    client(ip, port, "Hello World 3")

    server.shutdown()
    server.server_close()

以上是本人对socket相关的理解,有什么不当或错误之处,还请指出。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
Pythonの学習:2時間の毎日の研究で十分ですか?Pythonの学習:2時間の毎日の研究で十分ですか?Apr 18, 2025 am 12:22 AM

Pythonを1日2時間学ぶだけで十分ですか?それはあなたの目標と学習方法に依存します。 1)明確な学習計画を策定し、2)適切な学習リソースと方法を選択します。3)実践的な実践とレビューとレビューと統合を練習および統合し、統合すると、この期間中にPythonの基本的な知識と高度な機能を徐々に習得できます。

Web開発用のPython:主要なアプリケーションWeb開発用のPython:主要なアプリケーションApr 18, 2025 am 12:20 AM

Web開発におけるPythonの主要なアプリケーションには、DjangoおよびFlaskフレームワークの使用、API開発、データ分析と視覚化、機械学習とAI、およびパフォーマンスの最適化が含まれます。 1。DjangoandFlask Framework:Djangoは、複雑な用途の迅速な発展に適しており、Flaskは小規模または高度にカスタマイズされたプロジェクトに適しています。 2。API開発:フラスコまたはdjangorestFrameworkを使用して、Restfulapiを構築します。 3。データ分析と視覚化:Pythonを使用してデータを処理し、Webインターフェイスを介して表示します。 4。機械学習とAI:Pythonは、インテリジェントWebアプリケーションを構築するために使用されます。 5。パフォーマンスの最適化:非同期プログラミング、キャッシュ、コードを通じて最適化

Python vs. C:パフォーマンスと効率の探索Python vs. C:パフォーマンスと効率の探索Apr 18, 2025 am 12:20 AM

Pythonは開発効率でCよりも優れていますが、Cは実行パフォーマンスが高くなっています。 1。Pythonの簡潔な構文とリッチライブラリは、開発効率を向上させます。 2.Cのコンピレーションタイプの特性とハードウェア制御により、実行パフォーマンスが向上します。選択を行うときは、プロジェクトのニーズに基づいて開発速度と実行効率を比較検討する必要があります。

Python in Action:実世界の例Python in Action:実世界の例Apr 18, 2025 am 12:18 AM

Pythonの実際のアプリケーションには、データ分析、Web開発、人工知能、自動化が含まれます。 1)データ分析では、PythonはPandasとMatplotlibを使用してデータを処理および視覚化します。 2)Web開発では、DjangoおよびFlask FrameworksがWebアプリケーションの作成を簡素化します。 3)人工知能の分野では、TensorflowとPytorchがモデルの構築と訓練に使用されます。 4)自動化に関しては、ファイルのコピーなどのタスクにPythonスクリプトを使用できます。

Pythonの主な用途:包括的な概要Pythonの主な用途:包括的な概要Apr 18, 2025 am 12:18 AM

Pythonは、データサイエンス、Web開発、自動化スクリプトフィールドで広く使用されています。 1)データサイエンスでは、PythonはNumpyやPandasなどのライブラリを介してデータ処理と分析を簡素化します。 2)Web開発では、DjangoおよびFlask Frameworksにより、開発者はアプリケーションを迅速に構築できます。 3)自動化されたスクリプトでは、Pythonのシンプルさと標準ライブラリが理想的になります。

Pythonの主な目的:柔軟性と使いやすさPythonの主な目的:柔軟性と使いやすさApr 17, 2025 am 12:14 AM

Pythonの柔軟性は、マルチパラダイムサポートと動的タイプシステムに反映されていますが、使いやすさはシンプルな構文とリッチ標準ライブラリに由来しています。 1。柔軟性:オブジェクト指向、機能的および手続き的プログラミングをサポートし、動的タイプシステムは開発効率を向上させます。 2。使いやすさ:文法は自然言語に近く、標準的なライブラリは幅広い機能をカバーし、開発プロセスを簡素化します。

Python:汎用性の高いプログラミングの力Python:汎用性の高いプログラミングの力Apr 17, 2025 am 12:09 AM

Pythonは、初心者から上級開発者までのすべてのニーズに適した、そのシンプルさとパワーに非常に好まれています。その汎用性は、次のことに反映されています。1)学習と使用が簡単、シンプルな構文。 2)Numpy、Pandasなどの豊富なライブラリとフレームワーク。 3)さまざまなオペレーティングシステムで実行できるクロスプラットフォームサポート。 4)作業効率を向上させるためのスクリプトおよび自動化タスクに適しています。

1日2時間でPythonを学ぶ:実用的なガイド1日2時間でPythonを学ぶ:実用的なガイドApr 17, 2025 am 12:05 AM

はい、1日2時間でPythonを学びます。 1.合理的な学習計画を作成します。2。適切な学習リソースを選択します。3。実践を通じて学んだ知識を統合します。これらの手順は、短時間でPythonをマスターするのに役立ちます。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。