วันจันทร์ที่ 26 กันยายน พ.ศ. 2554

Socket

ในการส่งข้อมูลจากเครื่องคอมพิวเตอร์หนึ่งไปสู่อีกเครื่องหนึ่งในระบบเครือข่าย โปรแกรมด้านผู้ส่ง (sender) จะต้องนำข้อมูลที่ถูกส่งไปนั้น มาตัดออกเป็นส่วนย่อยๆ แล้วบรรจุลงใน packet แต่ละ packet จะมีส่วนประกอบสองส่วน ส่วนแรกคือ header เป็นข้อมูลเกี่ยวกับ address และ port ของผู้รับและผู้ส่ง รวมทั้งข้อมูลเท่าที่จำเป็นในการนำ packet มาประกอบกันเป็นข้อมูลเดิม อีกส่วนเรียกว่า payload คือข้อมูลย่อยที่จะถูกส่งไปนั้นเอง ผู้เขียนโปรแกรมจะต้องสร้างโปรแกรมทั้งด้านผู้ส่งและผู้รับ ที่ด้านผู้ส่งต้องทราบวิธีการสร้าง packet และส่ง packet ผ่านชั้นของโปรแกรมลงไปสู่ชั้นของตัวกลางเพื่อเดินทางไปในระบบเครือข่าย ที่ด้านผู้รับต้องทราบวิธีรับ packet จากระบบเครือข่าย ขึ้นมาประกอบเป็นลำดับที่ถูกต้อง แล้วจึงดึงข้อมูลออกมา จะเห็นว่าการเขียนโปรแกรมรับส่งข้อมูลผ่านระบบเครือข่ายเป็นเรื่องยุ่งยากมาก และต้องใช้ผู้เชี่ยวชาญในการสร้างโปรแกรมแบบนี้



จนกระทั่งใน Berkeley Unix มีการเสนอ Socket ขึ้นเพื่อใช้ในการเขียนโปรแกรมส่งข้อมูลผ่านระบบเครือข่าย โดยที่ socket ซ่อนรายละเอียดเกี่ยวกับ packet รวมทั้งวิธีการติดต่อกับระบบเครือข่ายไปจากผู้เขียนโปรแกรม แล้วให้ผู้เขียนโปรแกรมสามารถเขียนโปรแกรมรับส่งข้อมูลผ่านระบบเครือข่ายได้เหมือนกับการเขียนและอ่านข้อมูลจาก streams

เมื่อมี socket แล้ว การเขียนโปรแกรมส่งข้อมูลผ่านระบบเครือข่ายง่ายขึ้นอย่างมาก จึกแพร่หลายจาก UNIX ไปสู่ระบบปฏิบัติการอื่นๆ รวมทั้งยังอาจเขียนโปรแกรมเกี่ยวกับ socket ด้วยภาษาต่างๆโดยเริ่มจากภาษา C สู่ C++, VB , Java

ใน packet java.net มีคลาส Socket สำหรับสร้าง Socket ซึ่งมีกลไกสำหรับ
- สร้างการติดต่อไปสู่เครื่องเป้าหมายที่ port หนึ่ง โดยเครื่องเป้าหมายอาจเป็นผู้รับหรือส่งก็ได้
- สร้าง streams สำหรับอ่านหรือเขียนข้อมูลไปยังเครื่องเป้าหมาย
- ปิดการติดต่อไปสู่เครื่องเป้าหมาย

ในคลาส Socket มี constructor หลายตัวเช่น
public Socket(String,int) throws UnknowHostException , IOException;
public Socket(InetAddress,int) throw IOException;
จะสร้าง socket ไปยังเครื่อง host ที่ระบุโดยพารามิเตอร์ตัวแรกที่เป็น String หรือ InetAddress โดยติดต่อเข้าไปที่ port เลขที่ระบุด้วยพารามิเตอร์ตัวที่สองเป็น int

และยังมี constructor อีกสองตัวคือ
public Socket(String,int,InetAddress,int) throws IOException;
public Socket(InetAddress,int,InetAddress,int) throws IOException;
โดยทั้งคู่มีพารามิเตอร์สองตัวแรกระบุ host และ port ที่เครื่องเป้าหมาย ส่วนพารามิเตอร์ที่เป็น InetAddress และ int ต่อท้ายเพิ่มเข้ามาเพื่อระบุ host และ port ทางด้านผู้สร้าง socket เป็นเครื่องเริ่มต้น

ในการสร้าง instance ของคลาส Socket โดยการ new constructor เราต้องระบุค่า host ซึ่งเป็นเครื่องเป้าหมายที่ socket จะติดต่อไป และค่า port ที่เครื่องเป้าหมายนั้นเปิดรอรับไว้ หากที่เครื่องเป้าหมายไม่ได้เปิด port เบอร์นั้นไว้จะเกิด IOException โดยทั่วไปเราอาจระบุค่า host เป็น String ซึ่งจะใช้รูปแบบที่เป็น IP address คือ "xxx.xxx.xxx.xxx" หรือเป็น domain name ก็ได้ หากค่าของ host นั้นผิดพลาดหรือไม่มีอยู่จริงก็จะเกิด UnknowHostException สังเกตุว่า ถ้าเราระบุ host ด้วย InetAddress เป็นพารามิเตอร์ตัวแรก โปรแกรมจะทำงานได้เร็วกว่าระบุด้วย String เพียงเล็กน้อย

เมื่อเราสร้าง socket จะมีการติดต่อไปยังเครื่องเป้าหมายทันที โดยใช้ TCP/IP หลังจากเกิดการติดต่อแล้วนั้น เครื่องเริ่มต้นจะสามารถขอ input stream และ output stream จาก socket เพื่อทำการอ่านและเขียนไปยังเครื่องเป้าหมาย ดังนั้นต้องมีข้อตกลงระหว่างเครื่องทั้งสองว่า มีกติกาในการรับส่งข้อมูลอย่างไร เช่น ใครจะเป็นคนเขียนหรืออ่านก่อน เป็นต้น และข้อมูลต้องมีรูปแบบใด เราเรียกข้อตกลงนี้ว่า protocol เรากำหนดให้แต่ละ port ต้องมี protocol ที่แน่นอน เพื่อให้เราสามารถติดต่อเข้าไปที่ port นั้นได้ ถ้าเข้าใจ protocol แต่โปรแกรมนั้นอาจถูกเขียนด้วยภาษาใด หรือทำงานบน platform ใดก็ได้ ค่าของ port ต้องเป็นเลขจำนวนเต็ม มีค่าได้ตั้งแต่ 1-65535 แต่ในเครื่องทั่วไป port เบอร์ตั้งแต่ 1-1024 ถูกกำหนดเป็น port ที่มี protocol มาตรฐานไว้แล้ว เช่น 80 เป็น http , 21 เป็น ftp เป็นต้น ดังนั้นหากเราจะเปิด port เพื่อจะทำการติดต่อกันเอง ควรเลือกค่าที่สูงกว่า 1024 ขึ้นไป และตรวจสอบด้วยว่ามี โปรแกรมอื่นใช้ port เบอร์นั้นอยู่หรือไม่

2 ความคิดเห็น:

  1. ขอบคุณมากค่ะ ได้ประโยชน์จริงๆๆ

    ตอบลบ
  2. ขอบคุณครับ เป็นความรู้ที่ดีมากๆ......เลยครับ

    ตอบลบ