python ชนิดข้อมูลที่เล็กที่สุดสำหรับ socket chatter

"แพ็กเก็ต" ที่เล็กที่สุดที่สามารถส่งผ่านโมดูลซ็อกเก็ตคืออะไร ฉันต้องการส่งข้อมูล 16 บิต 2 ไบต์เท่านั้น และเป็นสิ่งที่ฉันต้องส่งอย่างรวดเร็ว ดังนั้นฉันจึงต้องการให้มีขนาดเล็กที่สุดเท่าที่จะเป็นไปได้ ฉันได้ทำ "การทดลอง" เพื่อค้นหาขนาดที่เล็กที่สุด ไม่มีอะไรที่ฉันได้รับจะน้อยกว่า 28 ไบต์

ผลการทดสอบ:

sys.getsizeof(2) = 28

sys.getsizeof(0b0001) = 28

sys.getsizeof(bytes(0b0001)) = 34

sys.getsizeof('0001') = 66

sys.getsizeof('a') = 60

sys.getsizeof(0b0001000100010001000100010001) = 28

sys.getsizeof(0b000100010001000100010001000100010001) = 32

ฉันแค่สงสัยว่านั่นเป็นสิ่งที่เล็กที่สุดที่ฉันสามารถส่งได้จริงหรือ


ฉันยังต้องการเพิ่มด้วยว่า python นั้นยากมากที่จะทำงานกับไบนารี่ ฉันรู้ว่ามันไม่มีความเกี่ยวข้องเหมือนเมื่อก่อน แต่สำหรับบางสิ่งมันก็มีประโยชน์ ฉันพูดแบบนี้ด้วยเหตุผลสองประการ:

1) ดูเหมือนว่าฉันไม่สามารถเก็บตัวแปรไบนารี่ได้ มันจะเปลี่ยนกลับเป็นจำนวนเต็มหรือประเภทอื่นเสมอ

2) จากการทดสอบฉันทำการแปลงไบนารีเป็นไบต์และได้ขนาดดังนี้:

sys.getsizeof(bytes(0b0001001001001001001001001)) = 2396778

person user1642826    schedule 06.09.2012    source แหล่งที่มา
comment
ค่าเหล่านี้เป็นค่าที่ขึ้นอยู่กับระบบในระบบของฉัน sizeof('a') = 25 และ `sizeof(2) = 12   -  person Joran Beasley    schedule 07.09.2012
comment
แล้วจะบังคับให้ซ็อกเก็ตรับเพียงสองบิตได้หรือไม่?   -  person user1642826    schedule 07.09.2012


คำตอบ (3)


sys.getsizeof ส่งคืนขนาดภายในของ Python int ไม่ใช่ C int คุณสามารถใช้ struct.pack เพื่อรับ C ไบต์:

>>> import struct
>>> struct.pack('H',32768)  # default endian-ness
'\x00\x80'
>>> struct.pack('>H',32768)  # force big-endian
'\x80\x00'

หากต้องการส่งไบต์ที่ชัดเจนสองไบต์:

>>> struct.pack('BB',100,200)
'd\xc8'

โปรดทราบว่าไบต์จะแสดงเป็นสตริง 'd' เป็นอักขระ ASCII สำหรับ 100 และ \xc8 เป็นสัญลักษณ์ฐานสิบหกสำหรับ 200:

>>> ord('d')
100
>>> 0xc8
200

คุณสามารถรับขนาดผลลัพธ์ของแพ็กเก็ตที่สร้างด้วย .pack ตัวอย่างเช่น ขนาดของกางเกงขาสั้นสองตัวและความยาว:

>>> struct.calcsize('>HHL')
8

ดูเอกสารประกอบของโมดูล struct

person Mark Tolonen    schedule 07.09.2012
comment
ขอบคุณนั่นคือสิ่งที่ฉันกำลังมองหา - person user1642826; 07.09.2012
comment
ยอดเยี่ยม! หากคำตอบเป็นที่ยอมรับ ให้คลิกเครื่องหมายถูกสีเขียวทางด้านซ้าย ยินดีต้อนรับสู่ Stack Overflow! - person Mark Tolonen; 07.09.2012

ตอบคำถามส่วนที่สองของคุณ:

"binary" เป็นตัวแทนของจำนวนเต็ม ไม่ใช่ประเภท คุณสามารถใช้ bin() เพื่อรับการแทนค่าไบนารี่เป็นสตริง คุณสามารถแปลงการแสดงสตริงไบนารีเป็น int โดยใช้.... int() เช่น.

>>> x = 1234
>>> bin(x)
'0b10011010010'     # note, this is a string
>>> print int(bin(x), 2)
1234

สำหรับส่วนที่สอง ฉันคิดว่าคุณต้องเข้าใจผิด:

>>> bytes(0b0001001001001001001001001)
'2396745'
>>> sys.getsizeof(bytes(0b0001001001001001001001001))
44
person mhawke    schedule 07.09.2012

จำนวนไบต์ที่ส่งผ่านซ็อกเก็ตนั้นขึ้นอยู่กับขนาดของค่าข้อมูลในภาษาการเขียนโปรแกรมเป็นอย่างมาก ตัวอย่างเช่น การส่งไบต์เดียวผ่านการเชื่อมต่อ TCP ใหม่ไปที่ "www.google.com:80" ส่งผลให้เกิดการไหลของแพ็กเก็ตต่อไปนี้:

A->B: 64 byte TCP SYN
B->A: 60 byte TCP SYN+ACK
A->B: 52 byte TCP ACK
A->B: 53 byte TCP packet containing a single byte payload
B->A: 52 byte TCP ACK
A->B: 52 byte TCP FIN
B->A: 52 byte TCP FIN+ACK
A->B: 52 byte TCP FIN

นั่นคือทั้งหมด 437 ไบต์ในการส่งเพย์โหลดไบต์เดียว UDP ให้อภัยได้มากกว่าเล็กน้อยส่งผลให้มีเพียง 29 ไบต์ที่ส่งสำหรับเพย์โหลดไบต์เดียว คุณสามารถบีบเพย์โหลดลงเหลือ 21 ไบต์ได้หากคุณใช้ซ็อกเก็ตดิบ

ไม่ว่าในกรณีใด การลดจำนวนไบต์ในเพย์โหลดลงเหลือ 1 และการใช้โปรโตคอลขั้นต่ำ (เช่น UDP ในกรณีส่วนใหญ่) จะดีเท่าที่คุณจะได้รับ ขนาดที่สำคัญคือ:

IP Header = 20 bytes
IP Header + UDP Header = 20 + 8 = 28 bytes
IP Header + TCP Header = 20 + 20 = 40 bytes

โปรโตคอลเครือข่ายต่างๆ ทั้งหมดจำกัดจำนวนไบต์ของเพย์โหลดเป็นไบต์ทั้งหมด

สิ่งที่ต้องจำอีกประการหนึ่งคือใต้ส่วนหัว IP คุณจะมีเลเยอร์กายภาพที่ซ่อนอยู่ด้านล่าง ในกรณีของอีเทอร์เน็ตมาตรฐาน ทุกอย่างจะถูกรวมเป็นแพ็กเก็ตขนาด 1,500 ไบต์ ไม่สำคัญว่าคุณจะส่ง 1 ไบต์หรือ 1,000 ไบต์ สุดท้ายคุณก็ต้องส่ง 1,500 ไบต์บนสาย แน่นอนว่านี่เป็นการลดความซับซ้อนครั้งใหญ่ แต่แนวคิดนี้ควรจะจมลงไป หากคุณใช้งานบนอีเทอร์เน็ตมาตรฐาน ฉันก็ไม่ต้องกังวลกับการส่งไบต์สักสองสามไบต์มากนัก จำกัดการใช้งานของคุณไว้ที่ UDP หากคุณไม่ต้องการการตอบรับ

หากคุณสนใจจริงๆ โปรดรับสำเนาซีรีส์ TCP/IP Illustrated อันศักดิ์สิทธิ์

person D.Shawley    schedule 08.09.2012