22. Network Programming

22.1. socket

22.1.1. Protokoły

  • IPv4 - socket.AF_INET
  • IPv6 - socket.AF_INET6
  • UDP - socket.SOCK_DGRAM
  • TCP - socket.SOCK_STREAM
  • Broadcast - socket.SO_BROADCAST

22.1.2. Otwieranie połączeń

Code Listing 22.19. Komunikacja za pomocą socketów
import socketserver

class UDPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        log.info('Received ping from %s:%s' % self.client_address)


if __name__ == '__main__':
    addr = ('localhost', 1234)

    logging.info('Listening for pings on %s...', addr)
    listener = socketserver.UDPServer(addr, UDPHandler)

    listener.serve_forever()

22.1.3. Nasłuchiwanie

import socket

HOST = '127.0.0.1'
PORT = 1337

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    s.sendall(b'Hello, world')
    data = s.recv(1024)

output = data.encode('utf-8')
print(output)

22.1.4. Przekazywanie informacji

import socket

HOST = '127.0.0.1'
PORT = 1337

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen(1)
    conn, addr = s.accept()

    with conn:
        while True:
            data = conn.recv(1024)

            if not data:
                break

            conn.sendall(data)

22.2. socketserver

22.2.1. Server

import socketserver


class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        data = self.request.recv(1024).strip()
        addr = self.client_address[0])

        print(f"From: {addr}, received: {data}"

        # just send back the same data, but upper-cased
        response = data.upper()
        self.request.sendall(response)


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

    with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
        # Activate the server; this will keep running until you
        # interrupt the program with Ctrl-C
        server.serve_forever()

22.2.2. Client

import socket
import sys

HOST, PORT = "localhost", 9999
data = "Hello World"


with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
    sock.connect((HOST, PORT))

    data = bytes(f'{data}\n', "utf-8")
    sock.sendall(data)

    # Receive data from the server and shut down
    received = str(sock.recv(1024), "utf-8")


print(f"Sent:     {data}")
print(f"Received: {received}")

22.2.3. Asynchronous

import socket
import threading
import socketserver


class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
    def handle(self):
        data = str(self.request.recv(1024), 'ascii')
        cur_thread = threading.current_thread()
        response = bytes(f"{cur_thread.name}: {data}", 'ascii')
        self.request.sendall(response)


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


def client(ip, port, message):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
        sock.connect((ip, port))
        sock.sendall(bytes(message, 'ascii'))
        response = str(sock.recv(1024), 'ascii')
        print(f"Received: {response}")


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

    with ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler) as server:
        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(f"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()

22.3. Biblioteki sieciowe

22.3.1. smtp

22.3.2. Zastosowania sieciowe

22.4. Automatyzacja pracy

22.4.1. fabric

from fabric.api import hosts

@hosts(['127.0.0.1', 'localhost'])
def whoami():
    sudo('whoami')

22.5. Allegro Ralph

Ralph is full-featured Asset Management, DCIM and CMDB system for data center and back office.

Features:

  • keep track of assets purchases and their life cycle
  • generate flexible and accurate cost reports
  • integrate with change management process using JIRA integration

It is an Open Source project provided on Apache v2.0 License.

Live demo:

22.6. ldap3

Code Listing 11.22.