นี่คือไดอะแกรมการตั้งค่าพื้นฐานในการรันโปรแกรมนี้
เพื่อความง่าย เราจะเรียก 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
- เซิร์ฟเวอร์.py:
นี่คือบรรทัด 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
- client.py:
การนำเข้าไลบรารี 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 สองระบบสำหรับเซิร์ฟเวอร์และไคลเอนต์
ข้อผิดพลาดที่คาดหวัง:
- คุณสามารถเห็นข้อผิดพลาดด้านล่างหากเซิร์ฟเวอร์ไม่ทำงานบนพอร์ต 9898
Traceback (การโทรล่าสุดล่าสุด):
ไฟล์'client.py',ไลน์22, ใน <โมดูล>NS.เชื่อมต่อ((เซิร์ฟเวอร์Ip,ท่า))
ข้อผิดพลาดในการเชื่อมต่อ:[Errno111]การเชื่อมต่อถูกปฏิเสธ
- ข้อผิดพลาดด้านล่างจะเห็นได้หากไม่ส่งที่อยู่ IP ที่ฝั่งไคลเอ็นต์
วิ่งอย่าง
ไคลเอนต์ python3พาย <ที่อยู่เซิร์ฟเวอร์>- ด้านล่างข้อผิดพลาดจะเห็นได้ถ้า1เซนต์อาร์กิวเมนต์ที่ฝั่งไคลเอ็นต์ไม่ใช่ที่อยู่ IP
Traceback (การโทรล่าสุดล่าสุด):
ไฟล์'client.py',ไลน์22, ใน <โมดูล>NS.เชื่อมต่อ((เซิร์ฟเวอร์Ip,ท่า))
เบ้า.ข้อผิดพลาด:[เออร์โน -2]ชื่อหรือบริการไม่เป็นที่รู้จัก
- ข้อผิดพลาดด้านล่างจะเห็นว่ามีการใช้พอร์ตเช่น 98980
Traceback (การโทรล่าสุดล่าสุด):
ไฟล์'client.py',ไลน์22, ใน <โมดูล>NS.เชื่อมต่อ((เซิร์ฟเวอร์Ip,ท่า))
OverflowError: getsockaddrarg: พอร์ตต้องเป็น0-65535.
- ข้อผิดพลาดด้านล่างจะเห็นได้หากไม่มี sample.txt ที่ฝั่งไคลเอ็นต์
Traceback (การโทรล่าสุดล่าสุด):
ไฟล์'client.py',ไลน์25, ใน <โมดูล>ไฟล์ = เปิด('ตัวอย่าง.txt', 'อาร์บี')
FileNotFoundError:[Errno2]ไม่มีไฟล์ หรือไดเรกทอรี:'ตัวอย่าง.txt'
บทสรุป:
เมื่อใช้โปรแกรมนี้ เราสามารถส่งไฟล์ข้อความธรรมดาจากระบบหนึ่งไปยังอีกระบบหนึ่งผ่านเครือข่ายโดยใช้โปรแกรมหลาม สิ่งนี้ทำให้เราเรียนรู้พื้นฐานเกี่ยวกับการเขียนโปรแกรมหลามและซ็อกเก็ตสำหรับการส่งข้อมูลผ่านเครือข่าย