การส่งข้อมูลระหว่าง client และ server ผ่าน socket - mrolarik/simple-iot GitHub Wiki

ตัวอย่างจำลอง การส่งข้อมูลระหว่าง client และ server ผ่าน socket สามารถทำได้โดย

โปรแกรมฝั่ง Server

  • เริ่มต้นที่สร้างไฟล์ภาษา Python ชื่อ server.py ไว้ในโฟลเดอร์ที่ต้องการ
  • โปรแกรมการทำงานในฝั่งของ Server มีดังต่อไปนี้
#-----------server.py-------------
import socket
import io

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = ''     # ip server
port = 12345  # define any number
s.bind((host, port))
s.listen(5)

while True:
    file = io.open("rpi.log", "a+")

    conn, addr = s.accept()
    print("Getting connection from", addr)
    conn.send("Server MSG: Thank you for connecting")
    client_msg = conn.recv(1024)

    print(client_msg)

    #file.write(client_msg+'\n')
    file.write(unicode(client_msg)+'\n')
    file.close()

conn.close()
  • โปรแกรมจะรอรับการเชื่อมต่อกับ Client เพื่อรับค่า เช่น ค่าจากเซนเซอร์ต่าง ๆ จาก RPi
  • โปรแกรมจะยังไม่แสดงข้อความใด ๆ จนกว่าเครื่อง Client เชื่อมต่อเข้ามา
  • เมื่อเชื่อมต่อกับ Client เสร็จเรียบร้อย Client จะส่งข้อมูลจากเซนเซอร์ และหมายเลขประจำเครื่อง RPi
  • จากนั้นจะบันทึกข้อมูลเก็บไว้ในไฟล์ชื่อ rpi.log
file = io.open("rpi.log", "a+")

โปรแกรมฝั่ง Client

#-----------rpi-client-01.py-------------
import time
import datetime
import socket

rpi_token_number = '#RPi123 '

while(True):
    s = socket.socket()
    host = ''      # ip server
    port = 12345   # port to connect

    s.connect((host, port))
    print(s.recv(1024))     # message from server

    dt = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    msg = 'client msg: ' + rpi_token_number + dt 

    print("sending: ", msg)

    s.send(str(msg))        # message to server
    s.close()
    time.sleep(3)
  • โปรแกรมจะส่งข้อมูลไปยัง Server โดยอ้างอิงจากหมายเลข ip ที่กำหนดไว้ในตัวแปร host
  • เมื่อเชื่อมต่อกับ Server เสร็จเรียบร้อย Client จะส่งข้อมูลจากเซนเซอร์ และหมายเลขประจำเครื่อง RPi
  • สามารถระบุหมายเลขประจำเครื่อง RPi จากตัวแปรดังต่อไปนี้
rpi_token_number = '#RPi123 '
  • ในที่นี้ระบุให้ rpi_token_number = '#RPi123'
  • ดังนั้น หากมี Client หลายตัว ให้เปลี่ยนหมายเลข rpi_token_number อย่าให้ซ้ำกัน เนื่องจากจะมีผลต่อการ query ข้อมูลไปใช้งาน

จากตัวอย่าง ข้อมูลที่ส่งออกไปประกอบด้วย

  • rpi_token_number = หมายเลขประจำเครื่อง Client
  • dt = date/time

การทำงานของโปรแกรม socket

ฝั่ง Server

  1. เริ่มต้นจากทางฝั่ง Server ให้พิมพ์คำสั่งดังต่อไปนี้
$ python server.py
  • เมื่อพิมพ์คำสั่ง python server.py โปรแกรมจะรอจนกว่าจะมีสัญญาณจากฝั่ง Client
  • ตัวอย่างหน้าจอการทำงานของฝั่ง Server ในกรณีที่ยังไม่มีสัญญาณจาก Client
    Server-Waiting
  1. หากมีสัญญาณจาก Client โปรแกรมทางฝั่ง Server จะเริ่มทำงาน ดังรูปภาพต่อไปนี้ Server-Working
  2. เมื่อโปรแกรมฝั่ง Server ทำงานสมบูรณ์ และไม่พบ Error ใด ๆ โปรแกรมจะบันทึกข้อมูลลงไปยังไฟล์ rpi.log log file
  • โดยใน rpi.log ไฟล์นั้นสามารถแยกข้อมูลตามหมายเลข #RPi

ฝั่ง Client

  1. จากนั้นทางฝั่ง Client ให้พิมพ์คำสั่ง ดังต่อไปนี้
$ python rpi-client-01.py
  1. หากโปรแกรมฝั่ง Client ทำงาน จะปรากฎข้อความ และทำการส่งข้อมูลไปยังฝั่ง Server Client-Sending Data
  2. หากโปรแกรมฝั่ง Server ยังไม่ได้ทำงาน จะขึ้นห้าจอ Error ทางฝั่งของ Client Client-Error
  • หากพบปัญหาดังกล่าว ให้กลับไปรันโปรแกรมที่ฝั่ง Server

ข้อดีของโปรแกรม Socket

  • โปรแกรมทางฝั่ง Client สามารถมีจำนวนเท่าไหร่ก็ได้ แค่เพียงจะต้องกำหนดหมายเลข ip address ของเครื่อง Server และ port ที่เชื่อมต่อให้ถูกต้อง
  • ตัวอย่างต่อไปนี้ แสดงการทำงานของ Client จำนวน 2 โปรแกรม โดยส่งข้อมูลไปยัง Server เดียวกัน multiple-client
  • โปรแกรมทางฝั่งของ Server ก็จะทำหน้าที่รับข้อมูลที่ส่งมาจาก Client ได้พร้อมกัน Server-Multi

ติดตั้งโปรแกรม Web Server

สร้างเว็บไซต์เพื่อเรียกดูข้อมูลจาก log file

  • เพื่อความสะดวกสบาย สามารถเขียนโปรแกรมเพื่อเรียกดูข้อมูลผ่านเว็บบราวเซอร์
  • แต่ทั้งนี้ที่ฝั่ง Server จะต้องติดตั้งโปรแกรม Web Server เช่น apache ให้เรียบร้อยก่อน และตรวจสอบสถานะการทำงานให้อยู่ในสถานะ start เสียก่อน
  • ตัวอย่างของโปรแกรม มีดังต่อไปนี้
//-----------index.php------------------
<h2> Client Msg: </h2>
<a href="javascript:location.reload(true)">Refresh this page</a>
<br/>
<?php
$filename = "rpi.log";   //กำหนด path ของไฟล์ที่ต้องการจะอ่านให้ถูกต้อง
$file = array_reverse(file($filename));  // แสดงข้อมูลจากบรรทัดล่างสุดก่อน
foreach($file as $line){
    echo $line."<br/>";
}
?>
  • จากนั้นเปิดเว็บบราวเซอร์ และพิมพ์ url ของ Server ที่ต้องการดูข้อมูล Web server

Reload หน้าเว็บเพจอัตโนมัติ

หากต้องการให้เว็บเพจทำการโหลดอัตโนมัติสามารถทำได้โดย

<head>
   <meta http-equiv="refresh" content="5;>
</head>

รายละเอียดเพิ่มเติม

⚠️ **GitHub.com Fallback** ⚠️