Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Einführung in Socket für fortgeschrittenes Python-Lernen

Detaillierte Einführung in Socket für fortgeschrittenes Python-Lernen

高洛峰
高洛峰Original
2017-03-19 14:57:521288Durchsuche

Die ursprüngliche englische Bedeutung von Socket ist „Loch“ oder „Buchse“. Als Prozesskommunikationsmechanismus von BSD UNIX wird er allgemein auch als „Socket“ bezeichnet, der zur Beschreibung von IP-Adressen und Ports verwendet wird. Er ist das Handle einer Kommunikationskette und kann zur Implementierung der Kommunikation zwischen verschiedenen virtuellen Maschinen oder verschiedenen Computern verwendet werden .

Zwei Programme im Netzwerk tauschen Daten über eine bidirektionale Kommunikationsverbindung aus. Ein Ende dieser Verbindung wird als Socket bezeichnet.

Mindestens ein Paar Portnummern (Socket) ist erforderlich, um eine Netzwerkkommunikationsverbindung herzustellen. Die Essenz von Socket ist die ProgrammierungSchnittstelle (API) Für die Kapselung von TCP/IP sollte TCP/IP diese ebenfalls bereitstellen für Programmierer Die für die Netzwerkentwicklung verwendete Schnittstelle ist die Socket-Programmierschnittstelle; HTTP ist das Auto, das eine spezifische Form der Kapselung oder Anzeige von Daten bereitstellt; Socket ist die Engine, die die Möglichkeit zur Netzwerkkommunikation bietet.

Lassen Sie uns über den Socket von Python sprechen.

1.socket-Modul

Verwenden Sie die Funktion socket.socket() , um einen Socket zu erstellen. Die Syntax lautet wie folgt:

socket.socket(socket_family,socket_type,protocol=0)

socket_family kann die folgenden Parameter sein:

socket.AF_INET IPv4 (Standard)

socket.AF_INET6 IPv6

socket.AF_UNIX kann nur für die prozessübergreifende Kommunikation in einem einzelnen Unix-System verwendet werden

socket_type kann die folgenden Parameter sein:

socket.SOCK_STREAM Streaming-Socket, für TCP (Standard)

socket.SOCK_DGRAM Datagramm-Socket, für UDP

socket.SOCK_RAW Raw-Socket, gewöhnlicher Socket kann ICMP nicht verarbeiten , IGMP und andere Netzwerknachrichten, aber SOCK_RAW kann auch spezielle IPv4-Nachrichten verarbeiten. Darüber hinaus kann der IP-Header vom Benutzer über die Socket-Option IP_HDRINCL erstellt werden.

Socket.SOCK_RDM ist eine zuverlässige Form von UDP, die die Zustellung von Datagrammen garantiert, jedoch nicht die Reihenfolge. SOCK_RAM wird verwendet, um Low-Level-Zugriff auf das Originalprotokoll bereitzustellen und wird verwendet, wenn bestimmte spezielle Vorgänge ausgeführt werden müssen, beispielsweise das Senden von ICMP-Nachrichten. SOCK_RAM ist normalerweise auf Programme beschränkt, die von Hauptbenutzern oder Administratoren ausgeführt werden.

socket.SOCK_SEQPACKET Zuverlässiger kontinuierlicher Paketdienst

Protokollparameter:

0 (Standard) Das Protokoll, das sich auf die spezifische Adressfamilie bezieht. Wenn es 0 ist, wird das System A Das geeignete Protokoll wird automatisch basierend auf dem Adressformat und dem Socket-Typ ausgewählt

2. SocketObjektEingebaute Methode

Serverseitige Socket-Funktion

s.bind()  Adresse (IP-Adresse, Port) an den Socket binden, die Parameter müssen im Format von Tupeln vorliegen. Zum Beispiel: s.bind(('127.0.0.1',8009))

s.listen(5) Beginnen Sie mit dem Abhören, 5 ist die maximale Anzahl ausstehender Verbindungen

s.accept() Akzeptieren Sie passiv Client-Verbindungen, blockieren Sie und warten Sie auf Verbindungen

Client-Socket-Word-Funktion

s.connect() Um eine Verbindung zum Server herzustellen, müssen die Parameter im Tupelformat vorliegen. Zum Beispiel: s.connect(('127,0.0.1',8009))

Öffentlicher Zweck Socket-Funktion

s.recv(1024) TCP-Daten empfangen, 1024 ist die Größe eines Datenempfangs

s.send(bytes) TCP-Daten senden, das Format von Python3 zum Senden von Daten muss im Byteformat vorliegen

s.sendall() Daten vollständig senden, interne Schleife Aufrufe senden

s.close() Socket schließen

Beispiel 1 .Einfache Implementierung des Socket-Programms

serverseitig

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import socket
import time
IP_PORT = ('127.0.0.1',8009)
BUF_SIZE = 1024
 
tcp_server = socket.socket()
tcp_server.bind(IP_PORT)
tcp_server.listen(5)
 
while True:
    print("waiting for connection...")
    conn,addr = tcp_server.accept()
    print("...connected from:",addr)
    while True:
        data = tcp_server.recv(BUF_SIZE)
        if not data:break
        tcp_server.send('[%s] %s'%(time.ctime(),data))
 
tcp_server.close()

Erklärung des obigen Codes:

1~4 Zeilen

Die erste Zeile ist die Unix-Startinformationszeile, und importieren Sie dann das Zeitmodul und das Socket-Modul

Zeilen 5 bis 10

IP_PORT deklariert die IP-Adresse und den Port für die globale -Variable und zeigt dies an Die Funktion bind() ist an diese Adresse gebunden. Stellen Sie die Puffergröße auf 1 KB ein. Die Funktion listen() gibt die maximale Anzahl an Verbindungen an, die gleichzeitig eingehen dürfen. Nachfolgende Verbindungen werden abgelehnt

11~到最后一行

在进入服务器的循环后,被动等待连接的到来。当有连接时,进入对话循环,等待客户端发送数据。如果消息为空,表示客户端已经退出,就跳出循环等待下一个连接到来。得到客户端消息后,在消息前面加一个时间戳然后返回。最后一行不会执行,因为循环不会退出所以服务端也不会执行close()。只是提醒不要忘记调用close()函数。

client端

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import socket
 
HOST = '127.0.0.1'
PORT = 8009
BUF_SIZE = 1024
ADDR = (HOST,PORT)
 
client = socket.socket()
client.connect(ADDR)
 
while True:
    data = input(">>> ")
    if not data:break
    client.send(bytes(data,encoding='utf-8'))
    recv_data = client.recv(BUF_SIZE)
    if not recv_data:break
    print(recv_data.decode())
     
client.close()

5~11行

HOST和PORT变量表示服务器的IP地址与端口号。由于演示是在同一台服务器所以IP地址都是127.0.0.1,如果运行在其他服务器上要做相应的修改。端口号要与服务器端完全相同否则无法通信。缓冲区大小还是1K。

客户端套接字在10行创建然后就去连接服务器端

13~21行

客户端也无限循环,客户端的循环在以下两个条件的任意一个发生后就退出:1.用户输入为空的情况或者服务器端响应的消息为空。否则客户端会把用户输入的字符串发送给服务器进行处理,然后接收显示服务器返回来的带有时间戳的字符串。

运行客户端程序与服务端程序

以下是客户端的输入与输出

[root@pythontab]# python client.py 
>>> hello python
[Thu Sep 15 22:29:12 2016] b'hello python'

以下是服务端输出

[root@pythontab]# python server.py 
waiting for connection...
...connected from: ('127.0.0.1', 55378)

3.socketserver模块

socketserver是标准库中的一个高级别的模块。用于简化实现网络客户端与服务器所需要的大量样板代码。模块中已经实现了一些可以使用的类。

实例1:使用socketserver实现与上面socket()实例一样的功能

服务端程序代码

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import socketserver
import time
 
HOST = '127.0.0.1'
PORT = 8009
ADDR = (HOST,PORT)
BUF_SIZE = 1024
 
class Myserver(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            print("...connected from:",self.client_address)
            data = self.request.recv(BUF_SIZE)
            if not data:break
            self.request.send(bytes("%s %s"%(time.ctime(),data)))
 
server = socketserver.ThreadingTCPServer(ADDR,Myserver)
print("waiting for connection...")
server.serve_forever()

11~17行

主要的工作在这里。从socketserver的BaseRequestHandler类中派生出一个子类,并重写handle()函数。

在有客户端发进来的消息的时候,handle()函数就会被调用。

19~21行

代码的最后一部分用给定的IP地址和端口加上自定义处理请求的类(Myserver)。然后进入等待客户端请求与处理客户端请求的无限循环中。

客户端程序代码

import socket
HOST = '127.0.0.1'
PORT = 8009
ADDR = (HOST,PORT)
BUF_SIZE = 1024
 
client = socket.socket()
client.connect(ADDR)
 
while True:
    data = input(">>> ")
    if not data:continue
    client.send(bytes(data,encoding='utf-8'))
    recv_data = client.recv(BUF_SIZE)
    if not recv_data:break
    print(recv_data.decode())
 
client.close()

执行服务端和客户端代码  

下面是客户端输出

[root@pythontab]# python socketclient.py 
>>> hello python
Thu Sep 15 23:53:31 2016 b'hello python'
>>> hello pythontab
Thu Sep 15 23:53:49 2016 b'hello pythontab'

下面是服务端输出

[root@pythontab]# python socketserver.py 
waiting for connection...
...connected from: ('127.0.0.1', 55385)
...connected from: ('127.0.0.1', 55385)
...connected from: ('127.0.0.1', 55385)
...connected from: ('127.0.0.1', 55385)

Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in Socket für fortgeschrittenes Python-Lernen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn