Python Socket File Transfer ส่ง

Python Socket File Transfer Send



ความตั้งใจของบทความนี้คือการเรียนรู้ วิธีถ่ายโอนไฟล์ข้อความผ่านเครือข่ายผ่านโปรแกรมหลาม . การถ่ายโอนไฟล์นี้อิงตามโมเดลไคลเอ็นต์เซิร์ฟเวอร์เพื่อใช้การเขียนโปรแกรมซ็อกเก็ตใน python3+

นี่คือไดอะแกรมการตั้งค่าพื้นฐานในการรันโปรแกรมนี้









เพื่อความง่าย เราจะเรียก System A เป็น A_client และ System B เป็น B_server ตลอดทั้งบทความ



ข้อกำหนดของไฟล์:

พวกเราต้องการ server.py และไฟล์นี้ควรอยู่ที่ระบบเซิร์ฟเวอร์ ในกรณีของเรา server.py ควรอยู่ที่ระบบ B_server





อีกสองไฟล์ client.py และ ตัวอย่าง.txt ควรมีอยู่ที่ระบบไคลเอนต์ ในกรณีของเราทั้งสองไฟล์ควรมีอยู่ในระบบ A_client

สมมติฐาน:

นี่คือสมมติฐาน:



  • เราควรมีระบบ Linux สองระบบที่มีการเข้าถึงเทอร์มินัล
  • รสชาติ Linux ที่ต้องการคือ อูบุนตู .
  • ควรติดตั้ง Python3
  • ระบบ Linux ทั้งสองระบบควรสามารถ ping กันได้ ใช้ ปิง คำสั่งตรวจสอบ ping
  • ระบบหนึ่งควรทำหน้าที่เป็นเซิร์ฟเวอร์ และระบบอื่นควรทำหน้าที่เป็นไคลเอนต์ในคราวเดียว

ข้อจำกัด:

ก่อนที่เราจะดำเนินการต่อ เราควรรู้ว่ามีข้อจำกัดบางประการของโปรแกรมนี้

  • ควรติดตั้ง Python3+ เพื่อเรียกใช้โปรแกรมนี้ คุณอาจสังเกตเห็นข้อผิดพลาดหรือพฤติกรรมที่แตกต่างกันหากทำงานบน python เวอร์ชันเก่า
  • เฉพาะไฟล์ข้อความเท่านั้นที่สามารถโอนผ่านโปรแกรมนี้ได้ ไฟล์รูปแบบอื่นที่ไม่มีข้อความอาจล้มเหลว
  • มีการจัดการข้อยกเว้นการเขียนโปรแกรมพื้นฐานในโปรแกรม
  • โปรแกรมอาจทำงานบนระบบปฏิบัติการอื่นที่ไม่ใช่ Ubuntu หรือไม่ก็ได้
  • ไฟล์ข้อความควรสั้นที่ฝั่งไคลเอ็นต์ เนื่องจากมีการใช้ขนาดบัฟเฟอร์ 1024 ไบต์

ตั้งค่าข้อกำหนด:

  • เราต้องการระบบ Linux อย่างน้อยหนึ่งระบบเพื่อทดลองใช้โปรแกรมนี้ แต่คำแนะนำคือการใช้ระบบลีนุกซ์สองระบบที่แตกต่างกันซึ่งเชื่อมต่อผ่านเครือข่าย
  • ควรเชื่อมต่อสองระบบผ่านอีเทอร์เน็ตหรือ Wi-Fi หรือการเชื่อมต่ออื่นๆ

รหัสที่มาของเซิร์ฟเวอร์:

https://github.com/linuxhintcode/websamples/blob/master/python_send_file/server.py

รหัสที่มาของลูกค้า:

https://github.com/linuxhintcode/websamples/blob/master/python_send_file/client.py

วิธีเรียกใช้โปรแกรมและผลลัพธ์ที่คาดหวัง:

นี่คือขั้นตอนในการรันโปรแกรม

ขั้นที่ 1: ไปที่ระบบ B_server และเปิดเทอร์มินัล ทางลัดในการเปิดเทอร์มินัลคือ Alt+Ctrl+t

ขั้นที่ 2: ไปที่เส้นทางที่มี server.py อยู่

ขั้นที่ 3: ตอนนี้เรียกใช้ server.py เหมือนด้านล่าง

เซิร์ฟเวอร์ python3พาย

ไม่ควรมีข้อผิดพลาดใด ๆ และคุณควรเห็นด้านล่างพิมพ์

เซิฟเวอร์อยู่ในพอร์ต : 9898

ชื่อไฟล์ที่คัดลอกจะเป็น recv.txt ที่ฝั่งเซิร์ฟเวอร์

ขั้นที่ 4: ตอนนี้เปิดเทอร์มินัลที่ระบบ A_client

ขั้นตอนที่ 5: ไปที่เส้นทางที่มี client.py และ sample.txt

ขั้นตอนที่ 6: ตอนนี้เรียกใช้ client.py ดังด้านล่าง

ไคลเอนต์ python3พาย <B_ระบบเซิร์ฟเวอร์ IP>

เราสังเกตว่าเราจำเป็นต้องทราบที่อยู่ IP ของเซิร์ฟเวอร์ เราสามารถรันคำสั่งด้านล่างเพื่อทราบที่อยู่ IP ของระบบ B_server

ifconfig

ตอนนี้เอาต์พุตของระบบ A_client ควรเป็นแบบนี้

##################### ได้รับข้อความด้านล่างจากเซิร์ฟเวอร์ ##################
| ---------------------------------- |
สวัสดีลูกค้า[ที่อยู่ IP: 192.168.1.102],
**ยินดีต้อนรับสู่เซิฟเวอร์**
-เซิร์ฟเวอร์
| ---------------------------------- |

ขั้นตอนที่ 7: ไปที่ B_server แล้วมองหาผลลัพธ์ด้านล่าง

คัดลอกไฟล์เรียบร้อยแล้ว
เซิร์ฟเวอร์ปิดการเชื่อมต่อ

ขั้นที่ 8: ควรมีชื่อไฟล์เดียว recv.txt ที่โฟลเดอร์เซิร์ฟเวอร์ เนื้อหาของ recv.txt นี้ควรเป็น sample.txt เดียวกัน

ดังนั้นเราจึงคัดลอกไฟล์จากไคลเอนต์ไปยังเซิร์ฟเวอร์ผ่านเครือข่ายผ่านโปรแกรมหลามได้สำเร็จ

คำอธิบายรหัส:

มีสองไฟล์หลาม server.py และ client.py .

โปรดทราบว่าเราจะอธิบายครั้งเดียวหากรหัสใดเหมือนกันใน server.py และ client.py

  1. เซิร์ฟเวอร์.py:
#!/usr/bin/env python3

นี่คือบรรทัด shebang ซึ่งหมายความว่าโดยค่าเริ่มต้น server.py นี้ควรใช้ python3 มาดูข้อดีอย่างหนึ่งของบรรทัดนี้กัน

เราได้ดำเนินการ server.py หรือ client.py like หลาม3 . ตอนนี้โดยไม่ต้องใช้ python3 เราสามารถรันไฟล์ python ได้ ทำตามคำสั่งด้านล่าง

ไปที่โหมดผู้ใช้ขั้นสูง:

ของมัน

ให้สิทธิ์ทั้งหมดกับไฟล์ .py:

chmod777เซิร์ฟเวอร์พาย

เรียกใช้ server.py:

./เซิร์ฟเวอร์พาย นำเข้า เบ้า
นำเข้าเบ้าไลบรารี่ลงในโปรแกรม pythonเช่นเรากำลังไป
ใช้เบ้า สำหรับการเชื่อมต่อ.

NS = เบ้า.เบ้า()

เรากำลังสร้างวัตถุ NS เพื่อเข้าถึงทุกวิธีของซ็อกเก็ต นี่คือแนวคิด OOP

ท่า= 9898

ตอนนี้เราเลือกพอร์ตหนึ่งที่เซิร์ฟเวอร์จะรับฟัง เราสามารถใช้พอร์ตที่ไม่สงวนไว้แทนสิ่งนี้

NS.ผูก(('',ท่า))

เราใช้วิธีผูกเพื่อผูกที่อยู่ IP ของเซิร์ฟเวอร์กับพอร์ตนั้น [9898] การสังเกตอย่างหนึ่งคือ เราสามารถใช้ที่อยู่ IP ที่แน่นอนของเซิร์ฟเวอร์แทนอาร์กิวเมนต์แรกของวิธีการผูก แต่เราเลือกที่จะเว้นว่างไว้เพราะวิธีนี้ใช้ได้ดี

NS.ผูก((ที่อยู่ IP,ท่า))
ไฟล์ = เปิด('recv.txt', 'wb')

เราได้เปิดชื่อไฟล์หนึ่งชื่อ recv.txt ในเซิร์ฟเวอร์สำหรับโหมดเขียนและได้รับตัวชี้ไฟล์ สิ่งนี้จำเป็นเนื่องจากเราต้องคัดลอกไฟล์ข้อความหนึ่งไฟล์จากลูกค้า

ในขณะที่ จริง:

มาเริ่มกันแบบไม่มีที่สิ้นสุดกันในขณะที่งานของเซิร์ฟเวอร์คือรอจนกว่าไคลเอนต์จะสื่อสารกับเซิร์ฟเวอร์บนพอร์ต 9898 นั้น ดังนั้นจึงจำเป็นต้องมีการวนซ้ำ

conn,addr=NS.ยอมรับ()

รหัสนี้คือการยอมรับคำขอเชื่อมต่อที่เข้ามาจากลูกค้า คอนจะใช้ conn เพื่อสื่อสารกับลูกค้าและ addr คือที่อยู่ IP ของลูกค้าที่ส่งคำขอความปั่นป่วนไปยังเซิร์ฟเวอร์นี้ที่พอร์ต 9898

ผงชูรส= 'NSNS| ---------------------------------- |NSสวัสดีลูกค้า[ที่อยู่ IP:
'
+ addr[0]+'],NS**ยินดีต้อนรับสู่เซิฟเวอร์**NS-เซิร์ฟเวอร์NS
| ---------------------------------- |NS NSNS'

รหัสนี้คือการสร้างข้อความเพื่อส่งให้กับลูกค้า ข้อความนี้ควรพิมพ์บนเทอร์มินัลไคลเอ็นต์ เป็นการยืนยันว่าลูกค้าสามารถสื่อสารกับเซิร์ฟเวอร์ได้

ต่อส่ง(ผงชูรสเข้ารหัส())

ตอนนี้เรามีข้อความพร้อมแล้วส่งให้ลูกค้าโดยใช้สิ่งนั้น ต่อ รหัสนี้ส่งข้อความถึงลูกค้าจริงๆ

RecvData=ต่อRecv(1024)

รหัสนี้ได้รับข้อมูลใด ๆ ที่ส่งจากฝั่งไคลเอ็นต์ ในกรณีของเรา เราคาดหวังเนื้อหาของ sample.txt ใน RecvData .

ในขณะที่Recvข้อมูล:

อีกครั้งหนึ่งในขณะที่วนรอบเงื่อนไข RecvData ไม่ว่างเปล่า ในกรณีของเราไม่ว่างเปล่า

ไฟล์.เขียน(RecvData)

เมื่อเรามีเนื้อหาข้างในแล้ว RecvData จากนั้นเราก็เขียนไปยังไฟล์นั้น recv.txt โดยใช้ตัวชี้ไฟล์ ไฟล์.

RecvData=ต่อRecv(1024)

พยายามรับอีกครั้งหากมีข้อมูลใด ๆ จากลูกค้า ครั้งหนึ่ง RecvData ไม่มีข้อมูลโค้ดจะทำลายลูป while

ไฟล์.ปิด()

นี่จะเป็นการปิดตัวชี้ไฟล์เมื่อเราเขียนไฟล์เสร็จแล้ว

ต่อปิด()

การดำเนินการนี้จะปิดการเชื่อมต่อกับลูกค้า

หยุดพัก

สิ่งนี้จะออกมาจาก infinite while loop ที่ B_server

  1. client.py:
นำเข้า sys

การนำเข้าไลบรารี sys เนื่องจากเราต้องการใช้สิ่งอำนวยความสะดวกในการโต้แย้งใน python

ถ้า (เลน(sys.argv) > 1):
เซิร์ฟเวอร์Ip= sys.argv[1]
อื่น:
พิมพ์('NSNSวิ่งอย่างNSpython3 client.pyNSNS')
ทางออก(1)

ขณะที่เราส่งที่อยู่ IP ของ B_server ตามชื่อไฟล์ client.py ขณะทำงาน เราจำเป็นต้องจับที่อยู่ IP ของเซิร์ฟเวอร์นั้นภายในไคลเอนต์

…..if (len(sys.argv) > 1): => เพื่อให้แน่ใจว่าผู้ใช้ส่งอาร์กิวเมนต์อย่างน้อยหนึ่งอาร์กิวเมนต์เป็นที่อยู่ IP และตรวจจับที่อยู่ IP นั้นได้ เซิร์ฟเวอร์ไอพี

หากผู้ใช้ไม่ผ่านอย่างน้อยหนึ่งรหัสอาร์กิวเมนต์แสดงความช่วยเหลือและออกมาจากรหัส

ท่า= 9898

นี่จะต้องเป็นพอร์ตเดียวกับที่กล่าวถึงที่ฝั่ง B_server

NS.เชื่อมต่อ((เซิร์ฟเวอร์Ip,ท่า))

รหัสนี้จะทำการเชื่อมต่อ TCP กับ IP ของเซิร์ฟเวอร์ด้วยพอร์ตนั้น สิ่งผิดปกติที่จุดนี้จะส่งผลให้เกิดความล้มเหลวในการเชื่อมต่อ

ไฟล์ = เปิด('ตัวอย่าง.txt', 'อาร์บี')

เรากำลังเปิด sample.txt ในโหมดอ่านเพื่ออ่านเนื้อหาเท่านั้น

ส่งข้อมูล= ไฟล์.อ่าน(1024)

อ่านเนื้อหาของไฟล์แล้วใส่เข้าไป ส่งข้อมูล ตัวแปร.

ในขณะที่ส่งข้อมูล:

เรากำลังเริ่มต้นหนึ่งในขณะที่วนรอบ if ส่งข้อมูล มีข้อมูล ในกรณีของเราถ้า sample.txt ไม่ว่างเปล่า ก็ควรมีข้อมูล

NS.ส่ง(ส่งข้อมูล)

ตอนนี้เราสามารถส่งเนื้อหาของ ตัวอย่าง.txt ไปยังเซิร์ฟเวอร์โดยใช้วัตถุซ็อกเก็ต NS.

ส่งข้อมูล= ไฟล์.อ่าน(1024)

อ่านอีกครั้งถ้ามีอะไรเหลือ ดังนั้นจะไม่มีอะไรให้อ่านจากไฟล์ ส่งข้อมูล จะว่างและจะออกมาจาก while loop

NS.ปิด()

นี่ไม่ใช่การปิดการเชื่อมต่อจากฝั่งไคลเอ็นต์

ภาพหน้าจอของ Ubuntu ฝั่งเซิร์ฟเวอร์

ภาพหน้าจอของ Ubuntu ฝั่งไคลเอ็นต์

ชุดค่าผสมที่ทดสอบแล้ว:

  • Linux เป็นเซิร์ฟเวอร์และ Linux เป็นไคลเอนต์: PASS
  • Linux เป็นไคลเอนต์และ Linux เป็นเซิร์ฟเวอร์: PASS
  • Linux เป็นเซิร์ฟเวอร์และ Windows10 เป็นไคลเอนต์: PASS
  • Linux เป็นไคลเอนต์และ Windows10 เป็นเซิร์ฟเวอร์: PASS

คำแนะนำคือการใช้ระบบ Linux สองระบบสำหรับเซิร์ฟเวอร์และไคลเอนต์

ข้อผิดพลาดที่คาดหวัง:

  1. คุณสามารถเห็นข้อผิดพลาดด้านล่างหากเซิร์ฟเวอร์ไม่ทำงานบนพอร์ต 9898

Traceback (การโทรล่าสุดล่าสุด):

ไฟล์'client.py',ไลน์22, ใน <โมดูล>
NS.เชื่อมต่อ((เซิร์ฟเวอร์Ip,ท่า))
ข้อผิดพลาดในการเชื่อมต่อ:[Errno111]การเชื่อมต่อถูกปฏิเสธ
  1. ข้อผิดพลาดด้านล่างจะเห็นได้หากไม่ส่งที่อยู่ IP ที่ฝั่งไคลเอ็นต์

วิ่งอย่าง

ไคลเอนต์ python3พาย <ที่อยู่เซิร์ฟเวอร์>
  1. ด้านล่างข้อผิดพลาดจะเห็นได้ถ้า1เซนต์อาร์กิวเมนต์ที่ฝั่งไคลเอ็นต์ไม่ใช่ที่อยู่ IP

Traceback (การโทรล่าสุดล่าสุด):

ไฟล์'client.py',ไลน์22, ใน <โมดูล>
NS.เชื่อมต่อ((เซิร์ฟเวอร์Ip,ท่า))
เบ้า.ข้อผิดพลาด:[เออร์โน -2]ชื่อหรือบริการไม่เป็นที่รู้จัก
  1. ข้อผิดพลาดด้านล่างจะเห็นว่ามีการใช้พอร์ตเช่น 98980

Traceback (การโทรล่าสุดล่าสุด):

ไฟล์'client.py',ไลน์22, ใน <โมดูล>
NS.เชื่อมต่อ((เซิร์ฟเวอร์Ip,ท่า))
OverflowError: getsockaddrarg: พอร์ตต้องเป็น0-65535.
  1. ข้อผิดพลาดด้านล่างจะเห็นได้หากไม่มี sample.txt ที่ฝั่งไคลเอ็นต์

Traceback (การโทรล่าสุดล่าสุด):

ไฟล์'client.py',ไลน์25, ใน <โมดูล>
ไฟล์ = เปิด('ตัวอย่าง.txt', 'อาร์บี')
FileNotFoundError:[Errno2]ไม่มีไฟล์ หรือไดเรกทอรี:'ตัวอย่าง.txt'

บทสรุป:

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