کتابخانه‌ی استاندارد · شبکه

یو دی پی net/udp

فرستادن و گرفتن بسته‌های UDP، با پخش همگانی و چندپخشی.

واردسازی شبکه.یو دی پی

UDP بسته‌های جدا می‌فرستد، بدون اتصال و بدون ضمانت رسیدن یا ترتیب؛ در عوض سریع و ساده است. برای DNS، بازی‌ها، پخش زنده و کشف دستگاه‌ها در شبکه‌ی محلی به کار می‌رود. هر بسته تا حدود ۱۵۰۰ بایت امن است.

سوکت UDP به یک طرف خاص بسته نیست. همان سوکت می‌تواند به نشانی‌های زیادی بفرستد و از هر کسی دریافت کند، و هر بسته فیلدهای from_host و from_port را دارد تا بدانید پاسخ را کجا بفرستید. هر ارسال یک بسته است و هر دریافت یک بسته‌ی کامل برمی‌گرداند، پس برخلاف TCP لازم نیست دنبال پایان پیام بگردید.

UDP را وقتی انتخاب کنید که پاسخ دیررس ارزشی ندارد (وضعیت بازی، خوانش حسگر، صدا) یا وقتی یک پرسش کوچک یک پاسخ کوچک می‌گیرد. وقتی هر بایت باید به ترتیب برسد، تی سی پی را به کار ببرید. برای پیدا کردن نشانی نام‌ها، بسته‌ی دی‌ان‌اس از پیش پروتکل DNS را روی UDP برایتان پیاده کرده است.

اشتباه‌های رایج

  • پایان مهلت شبیه بسته‌ی خالی است. دریافت هم وقتی مهلت گذشته و هم وقتی طرف مقابل واقعاً صفر بایت فرستاده، data خالی برمی‌گرداند؛ پس هرگز بسته‌ی خالی را پیام نکنید.
  • بافر کوچک بسته را می‌بُرد. بقیه‌ی بسته‌ای که از max بزرگ‌تر باشد دور ریخته می‌شود و برای فراخوانی بعدی نمی‌ماند. بزرگ‌ترین اندازه‌ای را که پروتکلتان اجازه می‌دهد بدهید (صفر برای دریافت یعنی ۶۵۵۳۶).
  • متن در بایت صفر تمام می‌شود. دریافت یک رشته می‌دهد؛ بسته‌های دودویی دریافت بایت لازم دارند.
  • فقط IPv4. سوکت‌ها، نشانی‌ها و گروه‌های چندپخشی همه IPv4 هستند.
  • هیچ چیز تضمین نمی‌شود. بسته‌ها ممکن است گم شوند، تکرار شوند یا جابه‌جا برسند؛ راهنمای تلاش دوباره پاسخ رایج را نشان می‌دهد.

پاسخ دادن به درخواست

سرور UDP یک درگاه را می‌گیرد و هر بسته را به نشانی‌ای که از آن آمده پاسخ می‌دهد. کارخواه از باز کردن استفاده می‌کند که خودش یک درگاه آزاد برمی‌دارد، یک بسته می‌فرستد و روی همان سوکت منتظر پاسخ می‌ماند. در هر دو طرف زمان انتظار بگذارید، چون اگر بسته‌ای گم شود دریافت تا ابد منتظر می‌ماند.

net-udp-guide-ping.salam
واردسازی شبکه.یو دی پی
واردسازی رشته

ناپایا سرور := یو دی پی.سوکت یو دی پی {}

تابع پاسخ‌گو():
    یو دی پی.تنظیم زمان انتظار(سرور، ۲۰۰۰)
    ناپایا شمار := ۰
    تا شمار < ۳:
        ب := یو دی پی.دریافت(سرور، ۱۵۰۰)
        اگر ب.داده == "":
            بشکن
        پایان
        شمار += ۱
        _ := یو دی پی.ارسال(سرور، ب.میزبان فرستنده، ب.درگاه فرستنده، "پونگ " + رشته.از عدد(شمار) + " برای " + ب.داده)
    پایان
پایان

تابع ریشه:
    سرور = یو دی پی.پیوند روی("127.0.0.1"، ۰)
    ن := نخ‌ساز(پاسخ‌گو)
    کارخواه := یو دی پی.باز کردن()
    یو دی پی.تنظیم زمان انتظار(کارخواه، ۲۰۰۰)
    هر نام در ["آلفا"، "بتا"، "گاما"]:
        _ := یو دی پی.ارسال(کارخواه، "127.0.0.1"، یو دی پی.درگاه(سرور)، نام)
        سرچاپ یو دی پی.دریافت(کارخواه، ۱۵۰۰).داده
    پایان
    نخ‌پیوند(ن)
    یو دی پی.بستن(کارخواه)
    یو دی پی.بستن(سرور)
پایان
خروجیپونگ 1 برای آلفا پونگ 2 برای بتا پونگ 3 برای گاما

گرفتن درگاه روی 127.0.0.1 با پیوند روی سرور را فقط برای همین رایانه نگه می‌دارد. پیوند روی همه‌ی نشانی‌ها گوش می‌دهد و برای سرویسی که باید از شبکه در دسترس باشد همان لازم است.

زمان انتظار و تلاش دوباره

UDP هیچ‌وقت نمی‌گوید بسته‌ای گم شده، پس کارخواهی که منتظر پاسخ است باید کمی صبر کند و دوباره بفرستد. با تنظیم زمان انتظار، اگر چیزی به‌موقع نرسد دریافت بسته‌ای با data خالی برمی‌گرداند. سرور این نمونه دو درخواست اول را نادیده می‌گیرد، همان‌طور که یک شبکه‌ی شلوغ ممکن است آن‌ها را بیندازد، و کارخواه تا گرفتن پاسخ یا تمام شدن تلاش‌ها دوباره می‌فرستد.

net-udp-guide-retry.salam
واردسازی شبکه.یو دی پی

ناپایا سرور := یو دی پی.سوکت یو دی پی {}

تابع سرور بدقلق():
    یو دی پی.تنظیم زمان انتظار(سرور، ۳۰۰۰)
    ناپایا دیده := ۰
    تا دیده < ۳:
        ب := یو دی پی.دریافت(سرور، ۱۵۰۰)
        اگر ب.داده == "":
            بشکن
        پایان
        دیده += ۱
        اگر دیده == ۳:
            _ := یو دی پی.ارسال(سرور، ب.میزبان فرستنده، ب.درگاه فرستنده، "رسید: " + ب.داده)
        پایان
    پایان
پایان

تابع بپرس(سوکت: یو دی پی.سوکت یو دی پی، درگاه: صحیح، پرسش: رشته، دفعه‌ها: صحیح): رشته:
    تکرار دفعه‌ها در ای:
        _ := یو دی پی.ارسال(سوکت، "127.0.0.1"، درگاه، پرسش)
        پاسخ := یو دی پی.دریافت(سوکت، ۱۵۰۰)
        اگر پاسخ.داده != "":
            برگشت پاسخ.داده
        پایان
        سرچاپ "تلاش"، ای + ۱، "بی‌پاسخ ماند"
    پایان
    برگشت ""
پایان

تابع ریشه:
    سرور = یو دی پی.پیوند روی("127.0.0.1"، ۰)
    ن := نخ‌ساز(سرور بدقلق)
    کارخواه := یو دی پی.باز کردن()
    یو دی پی.تنظیم زمان انتظار(کارخواه، ۲۰۰)
    جواب := بپرس(کارخواه، یو دی پی.درگاه(سرور)، "وضعیت؟"، ۵)
    اگر جواب == "":
        سرچاپ "سرور در دسترس نیست"
    وگرنه:
        سرچاپ "پاسخ:"، جواب
    پایان
    نخ‌پیوند(ن)
    یو دی پی.بستن(کارخواه)
    یو دی پی.بستن(سرور)
پایان
خروجیتلاش 1 بی‌پاسخ ماند تلاش 2 بی‌پاسخ ماند پاسخ: رسید: وضعیت؟

چون یک درخواست ممکن است دو بار برسد (نسخه‌ی اول فقط دیر رسیده بود، نه گم)، درخواستی که چیزی را تغییر می‌دهد باید شناسه داشته باشد تا سرور تکراری بودنش را بفهمد و بدون انجام دوباره‌ی کار پاسخ بدهد. DNS دقیقا همین‌طور کار می‌کند.

بسته‌های دودویی

پروتکل‌های فشرده عددها را به جای متن در بایت‌ها می‌گذارند. ارسال بایت یک تکه حافظه را به شکل یک بسته می‌فرستد و دریافت بایت یک بافر را پر می‌کند و فرستنده را در دو آرگومان آخرش برمی‌گرداند. بسته‌ی این نمونه یک بایت برای نوع پیام، یکی برای شماره‌ی حسگر و دو بایت برای مقدار دارد، بایت بالاتر اول، که ترتیب رایج شبکه است.

net-udp-guide-binary.salam
واردسازی شبکه.یو دی پی
واردسازی حافظه

تابع ریشه:
    گیرنده := یو دی پی.پیوند روی("127.0.0.1"، ۰)
    فرستنده := یو دی پی.باز کردن()
    یو دی پی.تنظیم زمان انتظار(گیرنده، ۲۰۰۰)

    بیرون := حافظه.تخصیص صفرشده(۸ برگردان طبیعی۶۴)
    ب := بیرون برگردان طبیعی۸*
    ب[۰] = ۱ برگردان طبیعی۸
    ب[۱] = ۴۲ برگردان طبیعی۸
    ب[۲] = ۱ برگردان طبیعی۸
    ب[۳] = ۴۴ برگردان طبیعی۸
    فرستاده := یو دی پی.ارسال بایت(فرستنده، "127.0.0.1"، یو دی پی.درگاه(گیرنده)، بیرون، ۴)
    سرچاپ فرستاده، "بایت فرستاده شد"

    بافر := حافظه.تخصیص صفرشده(۱۵۰۰ برگردان طبیعی۶۴)
    ناپایا میزبان := ""
    ناپایا درگاه := ۰
    تعداد := یو دی پی.دریافت بایت(گیرنده، بافر، ۱۵۰۰، میزبان، درگاه)
    د := بافر برگردان طبیعی۸*
    نوع پیام := د[۰] برگردان صحیح
    حسگر := د[۱] برگردان صحیح
    مقدار حسگر := (د[۲] برگردان صحیح) * ۲۵۶ + (د[۳] برگردان صحیح)
    سرچاپ تعداد، "بایت از"، میزبان، "رسید"
    سرچاپ "نوع"، نوع پیام، "حسگر"، حسگر، "مقدار"، مقدار حسگر

    حافظه.آزادسازی(بیرون)
    حافظه.آزادسازی(بافر)
    یو دی پی.بستن(فرستنده)
    یو دی پی.بستن(گیرنده)
پایان
خروجی4 بایت فرستاده شد 4 بایت از 127.0.0.1 رسید نوع 1 حسگر 42 مقدار 300

بسته‌ها را زیر حدود ۱۵۰۰ بایت نگه دارید. بسته‌های بزرگ‌تر را شبکه تکه می‌کند و اگر یک تکه گم شود کل بسته از دست می‌رود. هر وقت داده ممکن است بایت صفر داشته باشد از دریافت بایت به جای دریافت استفاده کنید، چون رشته در اولین بایت صفر تمام می‌شود.

پیدا کردن دستگاه‌ها در شبکه‌ی محلی

برای پیدا کردن یک چاپگر، میزبان یک بازی یا نسخه‌ی دیگری از برنامه‌تان در همان شبکه بدون دانستن نشانی‌اش، به جای یک رایانه به یک گروه بفرستید. با پیوستن به گروه پخش سوکت هر چیزی را که کسی به نشانی گروه بفرستد دریافت می‌کند؛ فعال‌سازی پخش در عوض اجازه می‌دهد به نشانی پخشِ کل شبکه، مثل 255.255.255.255، بفرستید. این نمونه به چیدمان شبکه بستگی دارد و این‌جا فقط کامپایل می‌شود. روی بیشتر رایانه‌ها شنیده شد: چاپگر در 192.168.1.50 را چاپ می‌کند، چون فرستنده بسته‌های گروهیِ خودش را هم دریافت می‌کند.

net-udp-guide-discovery.salam
واردسازی شبکه.یو دی پی

تابع ریشه:
    گروه := "239.255.42.99"
    درگاه := ۹۹۹۹
    شنونده := یو دی پی.پیوند(درگاه)
    اگر وارونه یو دی پی.پیوستن به گروه پخش(شنونده، گروه):
        سرچاپ "پیوستن به"، گروه، "نشد"
        برگشت ۱
    پایان
    یو دی پی.تنظیم زمان انتظار(شنونده، ۱۰۰۰)

    اعلام‌کننده := یو دی پی.باز کردن()
    _ := یو دی پی.ارسال(اعلام‌کننده، گروه، درگاه، "چاپگر در 192.168.1.50")

    ب := یو دی پی.دریافت(شنونده، ۱۵۰۰)
    اگر ب.داده == "":
        سرچاپ "کسی چیزی اعلام نکرد"
    وگرنه:
        سرچاپ "شنیده شد:"، ب.داده
    پایان
    _ := یو دی پی.ترک گروه پخش(شنونده، گروه)
    یو دی پی.بستن(اعلام‌کننده)
    یو دی پی.بستن(شنونده)
    برگشت ۰
پایان

نشانی‌های گروهی از 239.0.0.0 تا 239.255.255.255 برای استفاده‌ی خصوصی درون یک سازمان در نظر گرفته شده‌اند. هر برنامه‌ای که اعلام‌ها را می‌خواهد همان درگاه را می‌گیرد و به همان گروه می‌پیوندد.

گونه‌ها

سوکت یو دی پی Socket

ساختار سوکت یو دی پی
سوکت UDP.
نامانگلیسیگونهتوضیح
توصیفگرfdصحیح۶۴ = -1شناسه‌ی سوکت.
net-udp-Echo.salam
واردسازی شبکه.یو دی پی
واردسازی حافظه

تابع ریشه:
    گیرنده := یو دی پی.پیوند روی("127.0.0.1"، ۰)
    فرستنده := یو دی پی.باز کردن()
    سرچاپ یو دی پی.معتبر(گیرنده)، یو دی پی.معتبر(فرستنده)، یو دی پی.درگاه(گیرنده) > ۰
    یو دی پی.تنظیم زمان انتظار(گیرنده، ۲۰۰۰)
    سرچاپ یو دی پی.ارسال(فرستنده، "127.0.0.1"، یو دی پی.درگاه(گیرنده)، "سلام")
    ب := یو دی پی.دریافت(گیرنده، ۱۵۰۰)
    سرچاپ ب.داده، ب.میزبان فرستنده، ب.درگاه فرستنده > ۰
    _ := یو دی پی.ارسال به(فرستنده، "127.0.0.1"، یو دی پی.درگاه(گیرنده)، "دو")
    متن := "سه"
    _ := یو دی پی.ارسال بایت(فرستنده، "127.0.0.1"، یو دی پی.درگاه(گیرنده)، متن برگردان تهی*، متن.طول())
    سرچاپ یو دی پی.دریافت(گیرنده، ۱۵۰۰).داده
    بافر := حافظه.تخصیص صفرشده(۶۴ برگردان طبیعی۶۴)
    ناپایا میزبان := ""
    ناپایا درگاه := ۰
    سرچاپ یو دی پی.دریافت بایت(گیرنده، بافر، ۶۴، میزبان، درگاه)، میزبان
    یو دی پی.تنظیم زمان انتظار(گیرنده، ۱۰۰)
    سرچاپ "[" + یو دی پی.دریافت(گیرنده، ۱۵۰۰).داده + "]"
    یو دی پی.فعال‌سازی پخش(فرستنده، درست)
    سرچاپ یو دی پی.پیوستن به گروه پخش(گیرنده، "239.1.2.3") یا درست، یو دی پی.ترک گروه پخش(گیرنده، "239.1.2.3") یا درست
    ب۲ := یو دی پی.پیوند(۰)
    سرچاپ یو دی پی.معتبر(ب۲)
    یو دی پی.بستن(ب۲)
    یو دی پی.بستن(گیرنده)
    یو دی پی.بستن(فرستنده)
    حافظه.آزادسازی(بافر)
پایان
خروجیtrue true true 8 سلام 127.0.0.1 true دو 4 127.0.0.1 [] true true true

بسته Packet

ساختار بسته
یک بسته‌ی دریافتی.
نامانگلیسیگونهتوضیح
دادهdataرشته = ""محتوا؛ اگر در مهلت چیزی نرسد، خالی.
میزبان فرستندهfrom_hostرشته = ""نشانی فرستنده.
درگاه فرستندهfrom_portصحیح = 0درگاه فرستنده.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-udp-Echo.salam

تابع‌ها

پیوند Bind

تابع پیوند(port: صحیح): سوکت یو دی پی
سوکتی می‌سازد که روی درگاه داده‌شده در همه‌ی نشانی‌ها گوش می‌دهد؛ صفر یعنی درگاه آزاد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-udp-Echo.salam

پیوند روی BindOn

تابع پیوند روی(host: رشته، port: صحیح): سوکت یو دی پی
مثل پیوند، ولی فقط روی نشانی داده‌شده.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-udp-Echo.salam

باز کردن Open

تابع باز کردن(): سوکت یو دی پی
سوکتی بدون درگاه مشخص، برای فرستادن.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-udp-Echo.salam

درگاه Port

تابع درگاه(s: سوکت یو دی پی): صحیح
درگاه سوکت.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-udp-Echo.salam

معتبر Ok

تابع معتبر(s: سوکت یو دی پی): منطقی
اگر سوکت درست ساخته شده باشد، درست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-udp-Echo.salam

بستن Close

تابع بستن(s: سوکت یو دی پی)
سوکت را می‌بندد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-udp-Echo.salam

ارسال Send

تابع ارسال(s: سوکت یو دی پی، host: رشته، port: صحیح، data: رشته): صحیح
یک بسته به میزبان و درگاه می‌فرستد و تعداد بایت‌ها را برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-udp-Echo.salam

ارسال به SendTo

تابع ارسال به(s: سوکت یو دی پی، host: رشته، port: صحیح، data: رشته): صحیح
همان ارسال.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-udp-Echo.salam

ارسال بایت SendBytes

تابع ارسال بایت(s: سوکت یو دی پی، host: رشته، port: صحیح، ptr: تهی*، n: صحیح): صحیح
n بایت از حافظه را در یک بسته می‌فرستد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-udp-Echo.salam

دریافت Receive

تابع دریافت(s: سوکت یو دی پی، max: صحیح): بسته
یک بسته با حداکثر max بایت (۶۵۵۳۶ اگر max صفر باشد) دریافت می‌کند؛ بسته‌ی بلندتر بریده می‌شود. اگر مهلت تنظیم شده باشد و چیزی نرسد، بسته با data خالی برمی‌گردد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-udp-Echo.salam

دریافت بایت ReceiveBytes

تابع دریافت بایت(s: سوکت یو دی پی، buf: تهی*، max: صحیح، out_host &: رشته، out_port &: صحیح): صحیح
یک بسته را در حافظه می‌خواند، طولش را برمی‌گرداند (در پایان مهلت یا خطا منفی) و نشانی و درگاه فرستنده را می‌دهد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-udp-Echo.salam

فعال‌سازی پخش SetBroadcast

تابع فعال‌سازی پخش(s: سوکت یو دی پی، enable: منطقی)
فرستادن به نشانی پخش همگانی شبکه را مجاز می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-udp-Echo.salam

تنظیم زمان انتظار SetTimeout

تابع تنظیم زمان انتظار(s: سوکت یو دی پی، millis: صحیح)
دریافت حداکثر چند میلی‌ثانیه صبر کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-udp-Echo.salam

پیوستن به گروه پخش JoinMulticast

تابع پیوستن به گروه پخش(s: سوکت یو دی پی، group_ip: رشته): منطقی
به یک گروه چندپخشی می‌پیوندد تا بسته‌های آن را بگیرد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-udp-Echo.salam

ترک گروه پخش LeaveMulticast

تابع ترک گروه پخش(s: سوکت یو دی پی، group_ip: رشته): منطقی
گروه چندپخشی را ترک می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-udp-Echo.salam