خانه / آموزش‌ها / برنامه‌نویسی شبکه با سوکت (Socket Programming)

برنامه‌نویسی شبکه با سوکت (Socket Programming)

🐍 HomeOfPython
|
📅 1404/10/22

سطح مقدماتی (Beginner Level)

سوکت (Socket) نقطه پایانی یک ارتباط دوطرفه بین دو برنامه است که در شبکه اجرا می‌شوند. ماژول استاندارد socket در پایتون دسترسی سطح پایین به رابط شبکه سیستم‌عامل را فراهم می‌کند. قبل از نوشتن کد، باید با چند مفهوم کلیدی آشنا شویم:

  1. IP Address: آدرس یکتای دستگاه در شبکه (مثلاً 127.0.0.1 یا localhost).
  2. Port: یک عدد (۰ تا ۶۵۵۳۵) که مشخص می‌کند داده‌ها به کدام برنامه در کامپیوتر مقصد برسند.
  3. Protocol: قوانین انتقال داده. معروف‌ترین آن‌ها TCP (قابل اعتماد، اتصال‌گرا) و UDP (سریع، بدون اتصال) هستند.

ساخت یک سوکت ساده

برای استفاده از سوکت، ابتدا باید ماژول آن را وارد کرده و یک شیء سوکت بسازیم.

Python

مفاهیم سرور و کلاینت (TCP)

در مدل TCP، یک طرف Server (گوش‌دهنده) و طرف دیگر Client (درخواست‌دهنده) است.

  • bind: اختصاص IP و Port به سوکت (مخصوص سرور).
  • listen: شروع به گوش دادن برای تماس‌های ورودی (مخصوص سرور).
  • accept: قبول کردن یک تماس و ایجاد ارتباط (مخصوص سرور).
  • connect: تلاش برای اتصال به سرور (مخصوص کلاینت).
python
# Example 2: Basic TCP Server Structure (Static - Blocks Execution)
import socket

def start_server():
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # Bind to localhost on port 8080
    server.bind(('127.0.0.1', 8080))
    server.listen(5)
    print("Listening...")

    while True:
        # accept() blocks until a connection arrives
        client_socket, addr = server.accept()
        print(f"Connection from {addr}")
        client_socket.send(b"Hello from Server")
        client_socket.close()
python
# Example 3: Basic TCP Client Structure (Static - Requires running server)
import socket

def start_client():
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(('127.0.0.1', 8080))
    
    # Receive data (buffer size 1024 bytes)
    response = client.recv(1024)
    print(response.decode())
    client.close()

سطح پیشرفته (Professional Level)

در برنامه‌های واقعی، مدیریت منابع، استفاده از Context Managerها، تنظیم Timeout و مدیریت خطاهای شبکه حیاتی است. همچنین تفاوت‌های ظریف بین send و sendall باید در نظر گرفته شود.

استفاده از Context Manager (دستور with)

سوکت‌ها منابع سیستم‌عامل هستند و باید حتماً بسته شوند. استفاده از with تضمین می‌کند که حتی در صورت بروز خطا، سوکت بسته شود.

Python

تنظیمات پیشرفته و پورت‌های پرکاربرد (Port Reuse)

یکی از مشکلات رایج در توسعه سرور، خطای Address already in use پس از بستن و اجرای مجدد سریع برنامه است. برای جلوگیری از این مشکل، باید آپشن SO_REUSEADDR را تنظیم کنید.

python
# Example 5: Professional Server Setup with Reuse Address
import socket

def create_robust_server():
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    # Allow the reuse of the address immediately after close
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    
    server.bind(('0.0.0.0', 9000))
    server.listen()
    return server

تفاوت send و sendall

  • send(): ممکن است تمام داده‌ها را ارسال نکند. تعداد بایت‌های ارسال شده را برمی‌گرداند و برنامه‌نویس مسئول ارسال باقی‌مانده است.
  • sendall(): تا زمانی که تمام داده‌ها ارسال شوند یا خطایی رخ دهد، تلاش می‌کند. برای اکثر کاربردها ترجیح داده می‌شود.

سوکت‌های UDP

برخلاف TCP، پروتکل UDP نیازی به connect یا accept ندارد. داده‌ها به صورت بسته (Datagram) به آدرس مقصد "پرتاب" می‌شوند.

python
# Example 6: UDP Sender and Receiver Snippet
import socket

def udp_sender():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    msg = "This is UDP message".encode('utf-8')
    # No connect(), just sendto()
    sock.sendto(msg, ('127.0.0.1', 9999))

def udp_receiver():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(('127.0.0.1', 9999))
    data, addr = sock.recvfrom(1024)
    print(f"Received {data} from {addr}")

دریافت نام هاست و اطلاعات شبکه

پایتون ابزارهایی برای دریافت اطلاعات شبکه محلی ارائه می‌دهد که برای لاگ‌برداری یا تنظیمات دینامیک مفید است.

Python