Maison >développement back-end >Tutoriel Python >Introduction détaillée à socket pour un apprentissage avancé de Python

Introduction détaillée à socket pour un apprentissage avancé de Python

高洛峰
高洛峰original
2017-03-19 14:57:521329parcourir

La signification anglaise originale de Socket est « trou » ou « socket ». En tant que mécanisme de communication de processus de BSD UNIX, il est également communément appelé « socket », qui est utilisé pour décrire les adresses IP et les ports. Il s'agit du handle d'une chaîne de communication et peut être utilisé pour implémenter la communication entre différentes machines virtuelles ou différents ordinateurs. .

Deux programmes sur le réseau échangent des données via une connexion de communication bidirectionnelle. Une extrémité de cette connexion est appelée une prise.

Au moins une paire de numéros de port (socket) est requise pour établir une connexion de communication réseau. L'essence du socket est la ProgrammationInterface (API Pour l'encapsulation de TCP/IP, TCP/IP devrait également le fournir. pour les programmeurs L'interface utilisée pour le développement du réseau est l'interface de programmation Socket ; HTTP est la voiture, qui fournit une forme spécifique d'encapsulation ou d'affichage des données ; Socket est le moteur, qui permet la communication réseau.

Parlons du socket de python.

Le module 1.socket

utilise la fonction socket.socket() pour créer un socket. La syntaxe est la suivante :

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

socket_family peut être les paramètres suivants :

socket.AF_INET IPv4 (par défaut)

socket.AF_INET6 IPv6

socket.AF_UNIX ne peut être utilisé que pour la communication inter-processus dans un seul système Unix

socket_type peut être les paramètres suivants :

socket.SOCK_STREAM streaming socket, pour TCP (par défaut)

socket.SOCK_DGRAM Datagram socket, pour UDP

socket.SOCK_RAW raw socket, le socket ordinaire ne peut pas gérer ICMP , IGMP et d'autres messages réseau, mais SOCK_RAW le peut ; deuxièmement, SOCK_RAW peut également gérer des messages IPv4 spéciaux ; de plus, en utilisant des sockets bruts, l'en-tête IP peut être construit par l'utilisateur via l'option de socket IP_HDRINCL.

Socket.SOCK_RDM est une forme fiable d'UDP, qui garantit la livraison des datagrammes mais ne garantit pas la commande. SOCK_RAM est utilisé pour fournir un accès de bas niveau au protocole d'origine et est utilisé lorsque certaines opérations spéciales doivent être effectuées, telles que l'envoi de messages ICMP. SOCK_RAM est généralement limité aux programmes exécutés par des utilisateurs expérimentés ou des administrateurs.

socket.SOCK_SEQPACKET Service de paquets continu fiable

paramètre de protocole :

0 (par défaut) Le protocole lié à une famille d'adresses spécifique S'il est 0, le système A. le protocole approprié sera automatiquement sélectionné en fonction du format d'adresse et du type de socket

2. SocketObjectMéthode intégrée

Fonction de socket côté serveur

s.bind()  Lier l'adresse (adresse IP, port) au socket, les paramètres doivent être au format de tuples : s.bind(('127.0.0.1',8009))

s.listen(5) Commencer à écouter, 5 est le nombre maximum de connexions en attente

s.accept() Accepter passivement les connexions client, bloquer et attendre les connexions

Socket client Fonction Word

s.connect() Pour se connecter au serveur, les paramètres doivent être au format tuple Par exemple : s.connect(('127,0.0.1',8009))

Fonction Socket à usage public

s.recv(1024) Recevoir des données TCP, 1024 est la taille d'une réception de données

s.send(bytes) Envoyer des données TCP, le format d'envoi de données python3 doit être au format octets

s.sendall() Envoyer les données complètement, interne

boucle appelle send

s.close() Fermer le socket

Exemple 1 .Implémentation simple du programme socket

côté serveur

#!/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()
Explication du code ci-dessus :

1~4 lignes

La première ligne est la Ligne d'informations de démarrage Unix, puis importez le module d'heure et le module de socket

lignes 5 à 10

IP_PORT déclare l'adresse IP et le port de la

variable globale , indiquant que la fonction bind() est liée à cette adresse, définissez la taille du tampon sur 1K. La fonction Listen() indique le nombre maximum de connexions autorisées à entrer en même temps. Les connexions suivantes seront rejetées .

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)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn