لعبة خادم UDP والعميل في Go. لقد فعلت ذلك لأتعرف على حزمة Go القياسية net
، وتحديدًا الوظائف المتعلقة بـ UDP.
لأنني تعلمت أثناء كتابتي، أن هناك عدم تطابق غريب في الأسلوب بين كيفية عمل server.go لمآخذ توصيل UDP، وكيفية قيام Client.go ببعض الأمور المتعلقة بالمقبس "العامة". ولتسوية عدم التطابق هذا، قمت بإجراء Client2.go باستخدام وظائف UDP فقط لمطابقة server.go.
لقد أضفت أيضًا عميل Python 3، لأنه ليس لدي مكان آخر لوضعه فيه.
يستمع الخادم لحزم UDP على رقم منفذ معين. يقوم بحظر استدعاء الأسلوب net.ReadFromUDP()
.
في حالة تلقي الخادم بايتات، فإنه يطبع عدد البايتات التي استقبلها من المكان الذي استقبلها، ثم يكتب نفس عدد البايتات مرة أخرى إلى المكان الذي استقبلها منه.
يقوم العميل بإنشاء اتصال UDP ببعض عناوين IP (الإصدار 4 أو الإصدار 6) أو اسم المضيف ورقم المنفذ، بناءً على معلومات سطر الأوامر. ثم يكتب بايتات من سلسلة، أيضًا من سطر الأوامر، إلى اتصال UDP. وينتظر حتى تعود بعض البايتات إليه، أو يحدث خطأ. ثم إنه موجود.
بسيطة ولكنها مليئة بالمشاكل. لا توجد مهلات، لا يوجد عدد محدد من البايتات. يمكن أن يتعطل العميل أو الخادم إلى الأبد في انتظار الحزمة التي لا تصل أبدًا.
$ go build server.go
$ go build client.go
$ go build client2.go
يتم تفسير عميل python 3 ولا يحتاج إلى "بناء".
في النافذة 1:
$ ./server :: 7890
Accepting a new packet
في النافذة 2:
$ ./client udp localhost 7890 'some string'
أو:
$ ./client2 fe80::a11:96ff:fe7f:6d74 7890 'some string' [eth0]
أو:
$ ./client1.py localhost 7890 'some string'
الوسيطة النهائية لـ ./client2
اختيارية. إنه اسم واجهة الشبكة لتوجيه الحزم من خلالها. لاحظ محتويات net.UDPAddr
:
type UDPAddr struct {
IP IP
Port int
Zone string // IPv6 scoped addressing zone
}
يتم استخدام عنصر المنطقة لتوجيه عناوين الارتباط المحلية (fe80: البادئة). يعمل اسم الواجهة كمنطقة. يتم استدعاؤه باستخدام الوسيطة الرابعة، ويستخدم client2
هذه الوسيطة باعتبارها "المنطقة".