บทที่ 2 การเขียนโปรแกรมด้วย Socket

(Socket Programming)

วัตถุประสงค์การเรียนรู้

1) อธิบายหลักการทำงานของ Socket Programming ได้

2) เขียนโปรแกรม TCP Server ได้

3) เขียนโปรแกรม TCP Client ได้

4) เขียนโปรแกรมรับส่งข้อมูลด้วย UDP ได้

5) อธิบายความแตกต่างระหว่าง TCP และ UDP ในเชิงการเขียนโปรแกรมได้

https://python3.wannaphong.com/2015/01/socket-python-1.html https://www.borntodev.com/2020/05/12/socket-programming-%E0%B8%84%E0%B8%B7%E0%B8%AD%E0%B8%AD%E0%B8%B0%E0%B9%84%E0%B8%A3%E0%B8%AB%E0%B8%A7%E0%B9%88%E0%B8%B2/

2.1 บทนำ

การสื่อสารข้อมูลระหว่างโปรแกรมผ่านเครือข่ายเป็นพื้นฐานของระบบสารสนเทศและระบบโทรคมนาคมในปัจจุบัน ไม่ว่าจะเป็น Web Application ระบบ Internet of Things (IoT) ระบบ Cloud Computing ระบบควบคุมอุตสาหกรรม หรือระบบสื่อสารแบบเรียลไทม์ ต่างอาศัยการแลกเปลี่ยนข้อมูลผ่านเครือข่ายทั้งสิ้น

เนื้อหาในบทนี้มุ่งเน้นการเขียนโปรแกรมด้วยภาษา Python เนื่องจากเป็นภาษาที่มีไลบรารีสำหรับงานเครือข่ายครบถ้วน เข้าใจง่าย และได้รับความนิยมในงานด้านวิศวกรรมโทรคมนาคมและ Internet of Things

2.2 Socket API

2.2.1 ความหมายของ Socket API

Socket เป็นจุดเชื่อมต่อ (Endpoint) สำหรับการสื่อสารข้อมูลระหว่างโปรแกรมผ่านเครือข่าย อย่างไรก็ตาม โปรแกรมประยุกต์ไม่สามารถติดต่อกับฮาร์ดแวร์เครือข่ายหรือโปรโตคอล TCP/IP ได้โดยตรง แต่จะต้องอาศัย Socket API (Application Programming Interface) ซึ่งเป็นชุดคำสั่งที่ระบบปฏิบัติการจัดเตรียมไว้

Socket API ทำหน้าที่เป็นตัวกลางระหว่างโปรแกรมประยุกต์กับระบบเครือข่าย ช่วยให้นักพัฒนาสามารถสร้างการเชื่อมต่อ ส่งข้อมูล รับข้อมูล และยุติการเชื่อมต่อได้ โดยไม่จำเป็นต้องจัดการรายละเอียดระดับล่างของโปรโตคอล TCP/IP เช่น การแบ่งแพ็กเก็ต การตรวจสอบข้อผิดพลาด หรือการควบคุมการส่งข้อมูล ซึ่งเป็นหน้าที่ของระบบปฏิบัติการ

ในปัจจุบัน ภาษาโปรแกรมส่วนใหญ่ เช่น Python, C/C++, Java และ C# ต่างมีไลบรารีที่รองรับ Socket API ทำให้สามารถพัฒนาโปรแกรมเครือข่ายได้บนทุกระบบปฏิบัติการ

จากภาพจะเห็นว่า โปรแกรมประยุกต์ไม่ติดต่อกับโปรโตคอล TCP/IP โดยตรง แต่เรียกใช้ Socket API เพื่อส่งคำสั่งให้ระบบปฏิบัติการดำเนินการแทน

2.2.2 วงจรการทำงานของ Socket API

การรับส่งข้อมูลผ่าน Socket API มีขั้นตอนการทำงานแตกต่างกันเล็กน้อยระหว่างฝั่ง Server และ Client

ฝั่ง Server มีหน้าที่เปิดบริการและรอรับการเชื่อมต่อจาก Client

การทำงานของแต่ละขั้นตอนใน Socket Lifecycle (ฝั่ง Server) เพื่อให้เข้าใจง่ายและเห็นภาพการทำงาน

1) สร้าง Socket (Create Socket)

- ความหมาย: คือการประกาศตัวตนและสร้างช่องทางสื่อสารขึ้นมาในหน่วยความจำ เปรียบเทียบ: เหมือนการที่เราไปซื้อโทรศัพท์มือถือเครื่องใหม่มาตั้งไว้ที่บ้าน แต่ตอนนี้เครื่องยังไม่มีเบอร์และยังไม่ได้ต่อสาย

2) Bind IP และ Port

- ความหมาย: คือการผูก Socket ที่สร้างขึ้นเข้ากับ เลข IP Address (ระบุเครื่อง) และ Port Number (ระบุช่องทางของโปรแกรม) ของเซิร์ฟเวอร์ เปรียบเทียบ: เหมือนการนำซิมการ์ดไปลงทะเบียนเพื่อระบุเบอร์โทรศัพท์ให้กับเครื่องของเรา ทำให้คนอื่นรู้ว่าจะต้องโทรเข้าเบอร์ไหนถึงจะติดต่อโปรแกรมนี้ได้

3) Listen

- ความหมาย: คือการสั่งให้ Socket เปลี่ยนสถานะไปเป็น "ผู้รอฟัง" คอยสแตนด์บายรอการติดต่อเข้ามาจากฝั่ง Client และกำหนดจำนวนสายที่สามารถต่อคิวรอได้ (Queue) เปรียบเทียบ: เหมือนการเปิดเครื่องโทรศัพท์ทิ้งไว้ เปิดเสียงกระดิ่ง และนั่งรอให้มีคนโทรเข้ามา

4) Accept

- ความหมาย: เมื่อมี Client (ลูกค้า) ติดต่อเข้ามา เซิร์ฟเวอร์จะทำการ "ตอบรับสาย" และสร้างท่อเชื่อมต่อเฉพาะตัว (New Socket) แยกออกออกมาคุยกับลูกค้ารายนั้นโดยเฉพาะ เพื่อปล่อยให้ช่องทางหลัก (Listen) ทำหน้าที่รอรับสายอื่น ๆ ต่อไปได้ เปรียบเทียบ: เหมือนการกดปุ่มรับสายแล้วเริ่มสนทนา เพื่อตกลงเชื่อมต่อกันอย่างเป็นทางการ

5) Receive

- ความหมาย: เป็นขั้นตอนการ "รับข้อมูล" ที่ฝั่ง Client ส่งมา โดยเซิร์ฟเวอร์จะจอดรอ (Block) จนกว่าจะมีข้อมูลส่งมาในท่อสื่อสาร เปรียบเทียบ: เหมือนการนิ่งฟังสิ่งที่ปลายสายกำลังพูดหรือสั่งออเดอร์เข้ามา

6) Send

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

7) Close

- ความหมาย: คือการ "ปิดการเชื่อมต่อ" และคืนทรัพยากร (Memory/Port) ให้กับระบบปฏิบัติการเมื่อสิ้นสุดการทำงาน เพื่อให้ระบบไม่ค้างและพร้อมไปทำหน้าที่อื่นต่อ เปรียบเทียบ: เหมือนการกดวางสายหลังจากคุยธุระเสร็จเรียบร้อยแล้ว

ตัวอย่างโปรแกรมฝั่ง Server (ตัวรับข้อมู) ด้วย python

ให้สร้างไฟล์ชื่อ server.py แล้วใส่โค้ดนี้ลงไป


import socket

# 1. สร้าง Socket (ใช้ IPv4 และโปรโตคอล TCP)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 2. Bind IP และ Port 
# ใช้ '127.0.0.1' (localhost) สำหรับทดสอบในเครื่องตัวเอง และ Port 65432
HOST = '127.0.0.1'
PORT = 65432
server_socket.bind((HOST, PORT))
print(# สเต็ปที่ 2 บายด์ไอพีสำเร็จ
    f"[BIND] ผูก Socket เข้ากับ {HOST}:{PORT} เรียบร้อยแล้ว"
)

# 3. Listen (เริ่มรอสาย คอยฟังคำขอต่อสายจาก Client)
server_socket.listen()
print("[LISTEN] เซิร์ฟเวอร์กำลังเปิดเครื่องสแตนด์บาย รอคนติดต่อเข้ามา...")

# 4. Accept (กดรับสายเมื่อมี Client ต่อเข้ามา)
# จะได้ client_socket เอาไว้คุยแยกเฉพาะตัว และ client_address ที่บอกว่าใครโทรมา
client_socket, client_address = server_socket.accept()
print(f"[ACCEPT] ยอมรับการเชื่อมต่อจาก Client เบอร์: {client_address}")

try:
    # 5. Receive (นั่งรอฟังข้อมูลที่ Client ส่งมา)
    # 1024 คือขนาด Buffer ที่เปิดรับข้อมูล (ไบต์)
    data = client_socket.recv(1024)
    # แปลงข้อมูลจาก byte กลับมาเป็นข้อความอักษร (String) ด้วย utf-8
    message = data.decode('utf-8')
    print(f"[RECEIVE] ได้รับข้อความจากลูกค้าว่า: '{message}'")

    # 6. Send (ส่งข้อความตอบกลับไปหา Client)
    reply_message = "เซิร์ฟเวอร์ได้รับข้อมูลของคุณเรียบร้อยแล้วจ้า!"
    # ต้องแปลงข้อความอักษรให้เป็น byte ก่อนส่งด้วย .encode()
    client_socket.sendall(reply_message.encode('utf-8'))
    print("[SEND] ส่งข้อความตอบกลับไปยังลูกค้าแล้ว")

finally:
    # 7. Close (วางสาย ปิดท่อเชื่อมต่อเพื่อคืนทรัพยากร)
    client_socket.close()
    server_socket.close()
    print("[CLOSE] ปิดการเชื่อมต่อของ Socket ทั้งหมดเรียบร้อย")

ให้ทดลองโดยเปิดหน้าต่าง Terminal ด้วย command Prompt ขึ้นมา 2 หน้าต่าง โดยหน้าต่างที่ 1 ให้รันโปรแกรมที่เขียนขึ้นมา โดยใช้คำสั่ง python server.py เพื่อรันโปรแกรม และ ในหน้าต่างที่ 2 สามารถจำลองฝั่ง Client ได้ง่าย ๆ โดยไม่ต้องเขียนโค้ดเพิ่ม ด้วยการใช้คำสั่ง curl ยิงไปที่ Port



ตัวอย่างโปรแกรมฝั่ง client ด้วย python

ให้สร้างไฟล์ชื่อ client.py แล้วใส่โค้ดนี้ลงไป และให้ไว้ในโฟลเดอร์เดียวกันกับ server.py

โดยฝั่ง Client จะเริ่มเชื่อมต่อกับ Server ด้วยคำสั่ง connect() เชื่อมต่อไปยัง Server โดยต้องระบุ IP Address และ Port Number เช่น 172.26.26.50:5000 แต่หากใช้เครื่องคอมพิวเตอร์เครื่องเดียวกันในการทดสอบ ก็จะใช้ IP 127.0.0.1:5000


  import socket

# ระบุ IP และ Port ของ Server ที่เราต้องการจะโทรไปหา (ต้องตรงกับฝั่ง Server)
HOST = '127.0.0.1'
PORT = 65432

# 1. สร้าง Socket ของฝั่ง Client
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("[CREATE] สร้าง Client Socket สำเร็จ")

try:
    # 2. Connect (ทำการต่อสาย/เชื่อมต่อไปยัง Server ที่เปิดรออยู่)
    client_socket.connect((HOST, PORT))
    print(f"[CONNECT] เชื่อมต่อไปยังเซิร์ฟเวอร์ {HOST}:{PORT} สำเร็จแล้ว!")

    # 3. Send (ส่งข้อมูลออกไปหา Server)
    message = "สวัสดีครับเซิร์ฟเวอร์ นี่ข้อความจากฝั่ง Client นะ!"
    # แปลงข้อความจากตัวอักษรเป็นรูปแบบ Byte ก่อนส่งด้วย .encode()
    client_socket.sendall(message.encode('utf-8'))
    print(f"[SEND] ส่งข้อความออกไปว่า: '{message}'")

    # 4. Receive (นั่งรอฟังคำตอบที่ Server จะส่งสวนกลับมา)
    # ขนาด Buffer 1024 ไบต์
    data = client_socket.recv(1024)
    # แปลงข้อมูล Byte ที่ได้รับกลับมาเป็นข้อความตัวอักษรด้วย .decode()
    server_reply = data.decode('utf-8')
    print(f"[RECEIVE] เซิร์ฟเวอร์ตอบกลับมาว่า: '{server_reply}'")

except ConnectionRefusedError:
    print("[ERROR] ไม่สามารถเชื่อมต่อได้! กรุณาตรวจสอบว่าเปิดไฟล์ server.py ทิ้งไว้หรือยัง?")

finally:
    # 5. Close (คุยเสร็จแล้ว กดวางสายเพื่อคืนทรัพยากร)
    client_socket.close()
    print("[CLOSE] ปิดการเชื่อมต่อฝั่ง Client เรียบร้อย")

##########################################################################

ตัวอย่า่งโปรแกรมให้ ฝั่ง Server วนรับข้อความจาก Client และ ฝั่ง Client สามารถใช้คีบอร์ดพิมข้อความที่ต้องการและกดปุ่ม Enter เมื่อต้องการส่งข้อความ

โค้ดของฝั่ง Server


   import socket

HOST = '127.0.0.1'
PORT = 65432

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# บรรทัดนี้ช่วยให้กดรัน Server ซ้ำได้ทันทีโดยไม่ต้องรอเคลียร์ Port ค้าง
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

server_socket.bind((HOST, PORT))
server_socket.listen()
print("[LISTEN] เซิร์ฟเวอร์เปิดใช้งานแล้ว... รอ Client เชื่อมต่อเข้ามา")

client_socket, client_address = server_socket.accept()
print(f"[ACCEPT] ยอมรับการเชื่อมต่อจาก: {client_address}")

try:
    while True:
        # นั่งรอรับข้อความที่ฝั่ง Client กด Enter ส่งมา
        data = client_socket.recv(1024)
        if not data:
            break
            
        message = data.decode('utf-8')
        print(f"[RECEIVE] ลูกค้าพิมพ์ส่งมาว่า: '{message}'")
        
        # ถ้าลูกค้าพิมพ์คำว่า exit ให้ปิดลูปการคุยของลูกค้ารายนี้
        if message.lower() == 'exit':
            print("[EXIT] ลูกค้าขอวางสาย")
            break

        # ส่งคำตอบกลับไปหา Client ทันทีหลังจากที่เขา Enter มา
        reply_message = f"ได้รับข้อความ '{message}' เรียบร้อยแล้วนะ!"
        client_socket.sendall(reply_message.encode('utf-8'))

finally:
    client_socket.close()
    server_socket.close()
    print("[CLOSE] ปิดเซิร์ฟเวอร์เรียบร้อย")

โค้ดของฝั่ง Client


  import socket

HOST = '127.0.0.1'
PORT = 65432

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
    client_socket.connect((HOST, PORT))
    print(f"[CONNECT] เชื่อมต่อไปยังเซิร์ฟเวอร์ {HOST}:{PORT} สำเร็จ!")
    print("--------------------------------------------------")
    print("พิมพ์ข้อความแล้วกด [Enter] เพื่อส่ง (พิมพ์ 'exit' เพื่อเลิกคุย)")
    print("--------------------------------------------------")

    while True:
        # รับค่าที่เราพิมพ์จากคีย์บอร์ด
        user_message = input("คุณพิมพ์: ")
        
        # ถ้าไม่มีการพิมพ์อะไรเลย ให้ข้ามไปรอพิมพ์ใหม่
        if not user_message.strip():
            continue
            
        # ส่งข้อมูลออกไปหา Server
        client_socket.sendall(user_message.encode('utf-8'))
        
        # ถ้าพิมพ์คำว่า exit จะหลุดออกจากลูปเพื่อปิดโปรแกรม
        if user_message.lower() == 'exit':
            print("[EXIT] กำลังออกจากโปรแกรม...")
            break

        # นั่งรอฟังคำตอบที่ Server ส่งกลับมา
        data = client_socket.recv(1024)
        server_reply = data.decode('utf-8')
        print(f"เซิร์ฟเวอร์ตอบกลับมา: {server_reply}\n")

except ConnectionRefusedError:
    print("[ERROR] เชื่อมต่อไม่ได้! ลืมเปิด server.py หรือเปล่าครับ?")
finally:
    client_socket.close()
    print("[CLOSE] ปิดการเชื่อมต่อฝั่ง Client")

ให้ทดลองใช้คอมพิวเตอร์ 2 เครื่อง ให้เครืองแรกเป็นเซิฟเวอร์ โดยนำเลขหมาย IP จริง มาใส่ในโค้ดโปรแกรม และอีกเครืองทำหน้าที่เป็น Client แล้วนำเลขหมาย IP ของ Server มาใส่ในโค้ด แล้วทดลองส่งข้อความผ่านเครือข่าย โดยมีลักษณะดังรูป

การทำงานของ Socket API ทั้งสองฝั่งสามารถสรุปได้ดังภาพ

ลำดับการทำงานนี้เป็นพื้นฐานของโปรแกรมเครือข่ายแทบทุกประเภท ไม่ว่าจะเป็น Web Server, File Server, MQTT Broker หรือระบบรับข้อมูลจากอุปกรณ์ IoT

การประยุกต์ใช้ในระบบ IoT

พิจารณาระบบตรวจวัดอุณหภูมิด้วย ESP32 ดังรูป

ลำดับการทำงานของระบบมีดังนี้

1) Python Server เรียกใช้ socket(), bind(), และ listen() เพื่อเปิดรอรับการเชื่อมต่อ

2) ESP32 เรียกใช้ socket() และ connect() เพื่อเชื่อมต่อกับ Server

3) ESP32 ใช้ send() ส่งข้อมูลอุณหภูมิและความชื้น

4) Server ใช้ recv() รับข้อมูลและบันทึกลงฐานข้อมูล

5) Server ส่งข้อความตอบกลับ เช่น "OK" เพื่อยืนยันการรับข้อมูล

6) เมื่อการสื่อสารเสร็จสิ้น ทั้งสองฝั่งเรียกใช้ close() เพื่อยุติการเชื่อมต่อ

Socket API เป็นชุดคำสั่งพื้นฐานที่ใช้พัฒนาโปรแกรมเครือข่าย โดยทำหน้าที่เป็นตัวกลางระหว่างโปรแกรมประยุกต์กับระบบปฏิบัติการ คำสั่งหลัก ได้แก่ socket(), bind(), listen(), accept(), connect(), send(), recv() และ close() ซึ่งทำงานร่วมกันเพื่อสร้างการเชื่อมต่อ รับส่งข้อมูล และยุติการสื่อสาร ความเข้าใจในลำดับการทำงานของ Socket API เป็นพื้นฐานสำคัญก่อนศึกษาการพัฒนา TCP Server และ TCP

2.4 การเขียนโปรแกรม TCP Client

หลังจากได้ศึกษาการพัฒนา TCP Server ในหัวข้อที่ผ่านมา ซึ่งทำหน้าที่เปิดให้บริการและรอรับการเชื่อมต่อจากอุปกรณ์ต่าง ๆ แล้ว ในหัวข้อนี้จะศึกษาการพัฒนา TCP Client ซึ่งเป็นโปรแกรมที่ทำหน้าที่เริ่มต้นการเชื่อมต่อกับ Server เพื่อส่งข้อมูลหรือร้องขอบริการ

ในระบบเครือข่ายแบบ Client–Server การสื่อสารจะเกิดขึ้นเมื่อ Client ทำการเชื่อมต่อไปยัง Server ที่กำลังเปิดให้บริการ จากนั้นทั้งสองฝ่ายจึงสามารถรับส่งข้อมูลระหว่างกันได้

ในระบบเครือข่ายแบบ Client–Server การสื่อสารจะเกิดขึ้นเมื่อ Client ทำการเชื่อมต่อไปยัง Server ที่กำลังเปิดให้บริการ จากนั้นทั้งสองฝ่ายจึงสามารถรับส่งข้อมูลระหว่างกันได้

สำหรับงานด้านวิศวกรรมโทรคมนาคม TCP Client มักอยู่ในอุปกรณ์ปลายทาง เช่น ไมโครคอนโทรลเลอร์ เซนเซอร์อัจฉริยะ หรืออุปกรณ์ IoT ซึ่งทำหน้าที่ส่งข้อมูลที่ตรวจวัดได้ไปยัง Server เพื่อจัดเก็บ ประมวลผล หรือแสดงผล

ตัวอย่างเช่น

- ESP32 ส่งค่าอุณหภูมิไปยัง Server

- Smart Meter ส่งค่าการใช้พลังงานไฟฟ้า

- เครื่องวัดคุณภาพอากาศส่งข้อมูล PM2.5

- ระบบตรวจวัดระดับน้ำส่งค่าระดับน้ำไปยังศูนย์ควบคุม

ดังนั้น TCP Client จึงเป็นองค์ประกอบสำคัญของระบบ Internet of Things (IoT) และระบบตรวจวัดระยะไกล (Remote Monitoring System)

2.4.1 หลักการทำงานของ TCP Client

การทำงานของ TCP Client มีลำดับขั้นตอนดังนี้

1.สร้าง Socket

2.ระบุ IP Address และ Port ของ Server

3.เชื่อมต่อไปยัง Server

4.ส่งข้อมูล

5.รับข้อมูลตอบกลับ (ถ้ามี)

6.ปิดการเชื่อมต่อ

เมื่อเปรียบเทียบกับฝั่ง Server จะพบว่า Client มีขั้นตอนการทำงานน้อยกว่า เนื่องจากไม่ต้องรอรับการเชื่อมต่อหรือกำหนดหมายเลข Port สำหรับให้บริการ

2.4.2 การสร้าง TCP Client

การสร้าง TCP Client เริ่มต้นจากการสร้าง Socket โดยเลือกชนิดของ Socket เป็น TCP Socket จากนั้นจึงระบุหมายเลข IP Address และ Port Number ของ Server ที่ต้องการเชื่อมต่อ

หลังจากสร้าง Socket แล้ว Client จะเรียกใช้คำสั่ง connect() เพื่อสร้างการเชื่อมต่อไปยัง Server หาก Server เปิดให้บริการอยู่ การเชื่อมต่อจะสำเร็จ และทั้งสองฝ่ายจะเข้าสู่สถานะ Established ซึ่งพร้อมสำหรับการรับส่งข้อมูล

แต่หาก

- Server ยังไม่เปิด

- ระบุ IP Address ไม่ถูกต้อง

- ระบุ Port ผิด

- Firewall บล็อกการเชื่อมต่อ

การเชื่อมต่อจะล้มเหลว และโปรแกรมควรจัดการข้อผิดพลาดอย่างเหมาะสม

การส่งข้อมูล

เมื่อเชื่อมต่อสำเร็จ Client สามารถส่งข้อมูลไปยัง Server ได้ด้วยคำสั่ง send() ข้อมูลที่ส่งอาจเป็น ข้อความ ตัวเลข JSON ข้อมูลจากเซนเซอร์

การรับข้อมูลตอบกลับ

หลังจากส่งข้อมูลแล้ว Server อาจส่งข้อความตอบกลับมายัง Client เพื่อยืนยันว่ารับข้อมูลเรียบร้อยแล้ว เช่น Client ส่ง TEMP=30.6 แล้วServer ตอบกลับ OK

ข้อความตอบกลับช่วยให้ Client ทราบว่าการส่งข้อมูลสำเร็จ และสามารถดำเนินการขั้นต่อไปได้ เช่น แสดงสถานะบนหน้าจอ หรือส่งข้อมูลชุดถัดไป

การปิดการเชื่อมต่อ

เมื่อการรับส่งข้อมูลเสร็จสิ้น โปรแกรมควรเรียกใช้ close() เพื่อยุติการเชื่อมต่อและคืนทรัพยากรให้กับระบบปฏิบัติการ การปิดการเชื่อมต่ออย่างถูกต้องช่วยลดการใช้ทรัพยากรของระบบ และป้องกันปัญหาการเปิด Socket ค้าง (Socket Leak)

ตัวอย่างการทำงานของระบบ

ลำดับการทำงานของระบบมีดังนี้

1. ESP32 อ่านค่าอุณหภูมิและความชื้นจากเซนเซอร์

2. ESP32 สร้าง TCP Socket

3. ESP32 เชื่อมต่อไปยัง Server

4. ESP32 ส่งข้อมูลที่วัดได้

5. Server รับข้อมูลและตรวจสอบรูปแบบ

6. Server บันทึกข้อมูลลงฐานข้อมูล

7. Server ส่งข้อความ "OK" กลับไปยัง ESP32

8. ESP32 ปิดการเชื่อมต่อ

ข้อควรระวังในการพัฒนา TCP Client

ในการพัฒนาโปรแกรม TCP Client ควรคำนึงถึงประเด็นต่อไปนี้

- ตรวจสอบว่า Server พร้อมให้บริการก่อนเชื่อมต่อ

- จัดการกรณีการเชื่อมต่อล้มเหลว

- ตรวจสอบรูปแบบข้อมูลก่อนส่ง

- กำหนด Timeout เพื่อป้องกันการรอข้อมูลไม่สิ้นสุด

- ปิด Socket ทุกครั้งเมื่อใช้งานเสร็จ

นวทางเหล่านี้ช่วยเพิ่มความน่าเชื่อถือของระบบ โดยเฉพาะเมื่อนำไปใช้งานกับอุปกรณ์ IoT ที่ต้องทำงานต่อเนื่องเป็นเวลานาน

ตัวอย่างโค้ด TCP Client ด้วย Python

ตัวอย่างต่อไปนี้แสดงการสร้าง TCP Client เพื่อส่งข้อมูลอุณหภูมิไปยัง Server


import socket

HOST = "192.168.1.100"
PORT = 5000

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

client.connect((HOST, PORT))

message = "ID=001,TEMP=30.5,HUM=72.4"

client.send(message.encode())

reply = client.recv(1024)

print("Server:", reply.decode())

client.close()

คำอธิบายโปรแกรม

- socket.socket() สร้าง TCP Socket

- connect() เชื่อมต่อไปยัง Server

- send() ส่งข้อมูลไปยัง Server

- recv() รับข้อความตอบกลับจาก Server

- close() ปิดการเชื่อมต่อ

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

TCP Client เป็นโปรแกรมที่ทำหน้าที่เริ่มต้นการเชื่อมต่อกับ Server เพื่อส่งข้อมูลหรือร้องขอบริการ ขั้นตอนการทำงานประกอบด้วยการสร้าง Socket การเชื่อมต่อ การส่งข้อมูล การรับข้อมูลตอบกลับ และการปิดการเชื่อมต่อ สำหรับงานด้านวิศวกรรมโทรคมนาคม TCP Client มักทำงานอยู่ในอุปกรณ์ปลายทาง เช่น ESP32, Raspberry Pi หรืออุปกรณ์ IoT ซึ่งส่งข้อมูลที่ตรวจวัดได้ไปยัง Server เพื่อจัดเก็บในฐานข้อมูลและนำไปวิเคราะห์หรือแสดงผลบน Dashboard

หัวข้อ