खोज…


परिचय

कई प्रोग्रामिंग भाषाएं सॉकेट का उपयोग प्रक्रियाओं के बीच या उपकरणों के बीच संवाद करने के लिए करती हैं। यह विषय सामान्य नेटवर्किंग प्रोटोकॉल पर डेटा भेजने और प्राप्त करने की सुविधा के लिए पाइथन में सॉकेट्स मॉड्यूल के उचित उपयोग की व्याख्या करता है।

पैरामीटर

पैरामीटर विवरण
socket.AF_UNIX UNIX सॉकेट
socket.AF_INET आईपीवी 4
socket.AF_INET6 आईपीवी 6
socket.SOCK_STREAM टीसीपी
socket.SOCK_DGRAM यूडीपी

यूडीपी के माध्यम से डेटा भेजना

यूडीपी एक कनेक्शन रहित प्रोटोकॉल है। किसी भी प्रकार के कनेक्शन को स्थापित किए बिना अन्य प्रक्रियाओं या कंप्यूटरों को संदेश भेजे जाते हैं। यदि आपका संदेश प्राप्त हुआ है तो कोई स्वचालित पुष्टि नहीं है। यूडीपी आमतौर पर विलंबता संवेदनशील अनुप्रयोगों में या नेटवर्क वाइड प्रसारण भेजने वाले अनुप्रयोगों में उपयोग किया जाता है।

निम्न कोड UDP का उपयोग करके स्थानीयहोस्ट पोर्ट 6667 पर सुनने वाली प्रक्रिया को एक संदेश भेजता है

नोट वहाँ है, क्योंकि यूडीपी है "बंद" भेजने के बाद सॉकेट की आवश्यकता नहीं है कि संयोजन

from socket import socket, AF_INET, SOCK_DGRAM
s = socket(AF_INET, SOCK_DGRAM)
msg = ("Hello you there!").encode('utf-8')  # socket.sendto() takes bytes as input, hence we must encode the string first.
s.sendto(msg, ('localhost', 6667)) 

यूडीपी के माध्यम से डेटा प्राप्त करना

यूडीपी एक कनेक्शन रहित प्रोटोकॉल है। इसका मतलब है कि संदेश भेजने वाले साथियों को संदेश भेजने से पहले कनेक्शन स्थापित करने की आवश्यकता नहीं है। socket.recvfrom इस प्रकार एक टपल देता है ( msg [सॉकेट प्राप्त संदेश], addr [प्रेषक का पता])

UDP सर्वर केवल socket मॉड्यूल का उपयोग कर रहा है:

from socket import socket, AF_INET, SOCK_DGRAM
sock = socket(AF_INET, SOCK_DGRAM)
sock.bind(('localhost', 6667))

while True:
    msg, addr = sock.recvfrom(8192)  # This is the amount of bytes to read at maximum
    print("Got message from %s: %s" % (addr, msg))

नीचे socketserver.UDPServer का उपयोग कर एक वैकल्पिक कार्यान्वयन है।

from socketserver import BaseRequestHandler, UDPServer

class MyHandler(BaseRequestHandler):
    def handle(self):
        print("Got connection from: %s" % self.client_address)
        msg, sock = self.request
        print("It said: %s" % msg)
        sock.sendto("Got your message!".encode(), self.client_address) # Send reply

serv = UDPServer(('localhost', 6667), MyHandler)
serv.serve_forever()

डिफ़ॉल्ट रूप से, sockets ब्लॉक होता है। इसका मतलब है कि स्क्रिप्ट का निष्पादन तब तक इंतजार करेगा जब तक सॉकेट डेटा प्राप्त नहीं कर लेता।

टीसीपी के माध्यम से डेटा भेजना

कई मॉड्यूल का उपयोग करके इंटरनेट पर डेटा भेजना संभव है। सॉकेट्स मॉड्यूल अन्य कंप्यूटर या प्रक्रियाओं से डेटा भेजने या प्राप्त करने के लिए जिम्मेदार अंतर्निहित ऑपरेटिंग सिस्टम संचालन के लिए निम्न-स्तरीय पहुंच प्रदान करता है।

निम्न कोड बाइट स्ट्रिंग b'Hello' को होस्ट लोकलहोस्ट पर पोर्ट 6667 पर सुनने वाले टीसीपी सर्वर पर भेजता है और समाप्त होने पर कनेक्शन बंद कर देता है:

from socket import socket, AF_INET, SOCK_STREAM
s = socket(AF_INET, SOCK_STREAM)
s.connect(('localhost', 6667))  # The address of the TCP server listening
s.send(b'Hello')
s.close()

सॉकेट आउटपुट डिफ़ॉल्ट रूप से अवरुद्ध हो रहा है, इसका मतलब है कि प्रोग्राम कनेक्ट में इंतजार करेगा और कॉल को तब तक भेज देगा जब तक कि कार्रवाई पूरी नहीं हो जाती। कनेक्ट के लिए इसका मतलब है कि सर्वर वास्तव में कनेक्शन को स्वीकार कर रहा है। भेजने के लिए केवल इसका मतलब है कि ऑपरेटिंग सिस्टम में बाद में भेजे जाने वाले डेटा को कतार में रखने के लिए पर्याप्त बफर स्थान है।

उपयोग के बाद सॉकेट को हमेशा बंद रखना चाहिए।

मल्टी-थ्रेडेड टीसीपी सॉकेट सर्वर

जब कोई तर्कों के साथ नहीं चलाया जाता है, तो यह प्रोग्राम टीसीपी सॉकेट सर्वर शुरू करता है जो पोर्ट 5000 पर 127.0.0.1 कनेक्शन के लिए सुनता है। सर्वर प्रत्येक कनेक्शन को एक अलग थ्रेड में संभालता है।

-c तर्क के साथ चलने पर, यह प्रोग्राम सर्वर से जुड़ जाता है, क्लाइंट सूची पढ़ता है, और इसे प्रिंट करता है। क्लाइंट सूची को JSON स्ट्रिंग के रूप में स्थानांतरित किया जाता है। क्लाइंट का नाम -n तर्क पास करके निर्दिष्ट किया जा सकता है। विभिन्न नामों को पारित करके, ग्राहक सूची पर प्रभाव देखा जा सकता है।

client_list.py

import argparse
import json
import socket
import threading

def handle_client(client_list, conn, address):
    name = conn.recv(1024)
    entry = dict(zip(['name', 'address', 'port'], [name, address[0], address[1]]))
    client_list[name] = entry
    conn.sendall(json.dumps(client_list))
    conn.shutdown(socket.SHUT_RDWR)
    conn.close()

def server(client_list):
    print "Starting server..."
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(('127.0.0.1', 5000))
    s.listen(5)
    while True:
        (conn, address) = s.accept()
        t = threading.Thread(target=handle_client, args=(client_list, conn, address))
        t.daemon = True
        t.start()

def client(name):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('127.0.0.1', 5000))
    s.send(name)
    data = s.recv(1024)
    result = json.loads(data)
    print json.dumps(result, indent=4)

def parse_arguments():
    parser = argparse.ArgumentParser()
    parser.add_argument('-c', dest='client', action='store_true')
    parser.add_argument('-n', dest='name', type=str, default='name')
    result = parser.parse_args()
    return result

def main():
    client_list = dict()
    args = parse_arguments()
    if args.client:
        client(args.name)
    else:
        try:
            server(client_list)
        except KeyboardInterrupt:
            print "Keyboard interrupt"

if __name__ == '__main__':
    main()

सर्वर आउटपुट

$ python client_list.py
Starting server...

ग्राहक आउटपुट

$ python client_list.py -c -n name1
{
    "name1": {
        "address": "127.0.0.1", 
        "port": 62210, 
        "name": "name1"
    }
}

प्राप्त बफ़र 1024 बाइट्स तक सीमित हैं। यदि क्लाइंट सूची का JSON स्ट्रिंग प्रतिनिधित्व इस आकार से अधिक है, तो इसे छोटा कर दिया जाएगा। इससे निम्नलिखित अपवाद उत्पन्न होंगे:

ValueError: Unterminated string starting at: line 1 column 1023 (char 1022)

लिनक्स पर कच्चे सॉकेट

सबसे पहले आप अपने नेटवर्क कार्ड के स्वचालित चेकसमिंग को अक्षम करते हैं:

sudo ethtool -K eth1 tx off

फिर SOCK_RAW सॉकेट का उपयोग करके अपना पैकेट भेजें:

#!/usr/bin/env python
from socket import socket, AF_PACKET, SOCK_RAW
s = socket(AF_PACKET, SOCK_RAW)
s.bind(("eth1", 0))

# We're putting together an ethernet frame here, 
# but you could have anything you want instead
# Have a look at the 'struct' module for more 
# flexible packing/unpacking of binary data
# and 'binascii' for 32 bit CRC
src_addr = "\x01\x02\x03\x04\x05\x06"
dst_addr = "\x01\x02\x03\x04\x05\x06"
payload = ("["*30)+"PAYLOAD"+("]"*30)
checksum = "\x1a\x2b\x3c\x4d"
ethertype = "\x08\x01"

s.send(dst_addr+src_addr+ethertype+payload+checksum)


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow