เขียนโปรแกรม Client
/ Server ง่าย ๆ สไตล์ไพธอน !!
เขียนโดย อ.จักรกฤษณ์ แสงแก้ว สาขาสารสนเทศศาสตร์ คณะวิทยาการสารสนเทศ มหาวิทยาลัยมหาสารคาม
เขียน 11.25 น. วันที่ 8 กันยายน 2555
บทนำ
สำหรับวันนี้จะนำท่านศึกษาหลักการติดต่อสื่อสารระหว่าง Client และ Server ซึ่งอิมพลิเมนต์ด้วยภาษาไพธอน
โดยเราต้องเขียนโปรแกรมไว้สองฝั่ง คือ ฝั่ง Server และ Client ตามลำดับ
วัตถุประสงค์
- ศึกษาหลักการติดต่อสื่อสารระหว่าง Client และ Server ซึ่งอิมพลิเมนต์ด้วยภาษาไพธอน
ขั้นตอนการดำเนินงาน
การติดต่อสื่อสารระหว่าง Client และ Server จำเป็นต้องเขียนโปรแกรมไว้สองฝั่ง
คือ ฝั่ง Server และ Client ตามลำดับ ... โค๊ดต่อไปนี้จะช่วยให้มองเห็นความสามารถของไพธอนในการสร้างตัวเองเป็น
Server และทำตัวเองเป็น Client ในเวลาเดียวกัน
ขอให้พิจารณาโค๊ดต ฝั่ง Server !!
import socket
PORT = 8037
service = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
service.bind(("", PORT))
service.listen(1)
print "listening on port", PORT
while 1:
channel, info = service.accept()
print "connection from", info
channel.send("HEllo")
channel.close()
=======================================
โค๊ดในฝั่ง Client มีรายละเอียดดังนี้ :
=======================================
import socket
# ระบุหมายเลข IP และหมายเลขพอร์ตของเครื่อง Server
Host = "127.0.0.1"
Port = 8037
# สร้างการเชื่้อมต่อไปยังเครื่อง Server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((Host, Port))
# อ่านข้อมูลจากเครื่อง Server จำนวน 5 ตัวอักษร(ไบต์)
t = s.recv(5)
s.close()
# แสดงข้อมูลที่รับมาจากเครื่อง Server ให้ปรากฎที่จอภาพ
print "Received : ",t , " Len : ", len(t)
==============================================
การทำงานพอเป็นสังเขป :
1. ให้เครื่อง Server รันสคริปต์ทิ้งเอาไว้
2. เมื่อไรที่ Client เข้ามาที่เครื่องของเซอร์เวอร์ให้ทำงานตามเงื่อนไข
#python server.py
listening on port 8037
ถ้าเครื่อง Client เรียกใช้คำสั่งต่อไปนี้
#python client.py
ผลลัพธ์คือ
Received : HEllo Len : 5
ในขณะที่ฝั่ง Server จะแสดงข้อความว่า :
connection from ("xx.xx.xx.xx", xxxx)
ในตัวอย่างนี้ได้ใช้โมดูล socket และกำหนดหมายเลขพอร์ทไว้ที่ 8037 ซึ่งเป็นหมายเลขที่กำหนดขึ้นโดยตัวโปรแกรมเมอร์เอง
จากนั้นสร้างอินสแตนท์ชื่อ service ซึ่งถ่ายทอดมาจากคลาส socket.socket()
อาร์กิวเมนต์ของการสร้างคลาส socket คือ socket.AF_INET และ socket.SOCK_STREAM
เป็นการกำหนดข้อตกลงในการเชื่อมต่อแบบสตรีม
ลำดับถัดมาผูกการให้บริการเข้ากับพอร์ท ด้วยคำสั่ง socket.bind() โดยมีอาร์กิวเมนต์สองตัวคือ
สตริงเปล่า และตัวแปร PORT ซึ่งเก็บหมายเลขพอร์ท 8037 จากนั้นสั่ง listen() เพื่อให้แม่ข่ายรอตอบสนองเครื่องลูกข่าย
ในขณะที่กำลังรอการติดต่อระหว่างเครื่องลูกข่าย อ็อบเจ็ค service จะเรียกฟังก์ชั่น
accept() ซึ่งจะคืนค่าเป็นลีสต์ 2 อัน อันแรกคือ ช่องทางการเชื่อมต่อ ผู้เขียนให้เก็บไว้ในตัวแปร
channel ในขณะที่ลีสต์อีกตัวหนึ่งสำหรับข้อมูลจากเครื่องลูกข่าย ผู้เขียนกำหนดไว้ในตัวแปร
info
เมื่อมีการร้องขอจากลูกข่ายจะแสดงคำว่า "connection from" , info ซึ่งตัวแปร
info จะเก็บหมายเลข IP และพอร์ทที่ใช้เชื่อมต่อจากลูกข่าย
ลำดับถัดมาส่งข้อความคำว่า "HEllo" ออกไปยังช่องทางที่ได้รับการเชื่่อมต่อจากแม่ข่ายและลูกข่าย
เมื่อส่งข้อความเสร็จเรียบร้อย ให้ปิดช่องทางการสื่อสาร
พิจารณาที่ฝั่งลูกข่าย เมื่อเรียกคำสั่ง python client.py ไพธอนจะแปลความดังรายละเอียดต่อไปนี้
ตัวแปร Host ใช้เก็บหมายเลข IP Address ของเครื่องแม่ข่าย (ค่า default คือ 127.0.0.1
สำหรับเครื่องที่จำลองการเชื่อมต่อเน็ตเวอร์ค)
ตัวแปร Port กำหนดให้ตรงกันกับพอร์ทที่แม่ข่ายกำหนดไว้ จากนั้น สร้างอินสแตนท์ของคลาส
socket.socket() โดยผู้เขียนให้ชื่ออ็อบเจ็ค s การสร้างอินสแตนท์ทำเหมือนสคริปต์ฝั่งแม่ข่าย
จากนั้นเรียกใช้คำสั่ง connect() ภายในอ็อบเจ็ค s โดยระบุอาร์กิวเมนต์แรกคือหมายเลข
IP Address ของเครื่องแม่ข่าย และอาร์กิวเมนต์ที่สองคือหมายเลขพอร์ทที่ใช้เชื่อมต่อกับแม่ข่าย
ลำดับถัดมาทำการอ่านข้อมูลออกมาจากเครื่องแม่ข่ายเป็นจำนวน 5 ไบต์ ด้วยคำสั่ง recv()
และเก็บไว้ภายในตัวแปร t จากนั้นปิดคอนเน็คชั่นด้วยคำสั่ง close()
ผลลัพธ์ที่เก็บไว้ในตัวแปร t สามารถนำไปใช้งานต่อไปได้ ในตัวอย่างนี้แสดงให้ปรากฎบนจอภาพคอมพิวเตอร์
และแสดงจำนวนความยาวของตัวแปร t ซึ่งมีค่า 5 ไบต์
สรุป
สำหรับวันนี้ คงทำให้ท่านได้แนวคิดในการสร้างแอพลิเคชั่นไว้ใช้งานเองในแบบ Client/Server
หลักการนี้ เป็นหัวใจสำคัญของแอพลิเคชั่น Server ต่าง ๆ เช่น Apache Webserver,
FTP, Telnet เป็นต้น หวังว่าท่านจะสามารถไปประยุกต์ใช้กับงายของท่านได้.. สำหรับวันนี้
ขอยุติการบรรยายไว้เพียงเท่านี้ พบกันใหม่โอกาสหน้า.. สำหรับวันนี้ สวัสดีครับ