@2018年12月29日
一、背景
在之前两篇博客中,学习记录了python控制LED灯、套接字C/S通信。如
1.树莓派学习笔记1:python控制双色LED灯(https://blog.csdn.net/weixin_44230447/article/details/85223640)
2.Python学习笔记1:套接字编程-服务和客户端(https://blog.csdn.net/weixin_44230447/article/details/85267244)
基本原理和简单程序实现后,元旦期间对程序又进行了修改,主要是服务端程序修改较多。
二、基本原理和实验环境
1.硬件:树莓派及LED,参考树莓派学习笔记1
2.软件:
服务端程序,部署在树莓派上,host 如192.168.1.107;
客户端程序,本地pc上,可以是一python程序,也可是telnet工具。
树莓派和客户端终端,都接入一个局域网。跨域的还没试过。
在客户端通过 socket与远端建立TCP连接,发送指令字符到树莓派上服务端程序,按指令调用GPIO语句,控制电平高低,最终控制红绿LED的开关。
# -*- coding:utf-8 -*-
# Socket Server example in python 3.6
# 文件名:Socket_server_test.py
import socket
import sys
import RPi.GPIO as GPIO
import time
# ------------------------------------------------------------------
HOST = '' # Symbolic name meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port
timeout_limit=120 # unit-sec,建立连接后如果超过xx 秒,将断开连接
connect_times_limit=5 # unit-times,连接中断次数达到xx 次,将关闭socket和中止服务端程序。
#------------------------------------------------------------------
pins = {'pin_R':11, 'pin_G':12} # pins is a dict
sleep_time = 5
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
for i in pins:
GPIO.setup(pins[i], GPIO.OUT) # Set pins' mode is output
GPIO.output(pins[i], GPIO.LOW) # Set pins to low(0V) to off led
print("i is ",i,pins[i])
def Let_Led_on(pin):
print('The pin is',pin)
if pin=='pin_R' :
other_pin='pin_G'
elif pin=='pin_G' :
other_pin='pin_R'
else :
print('Input error.\r\n')
GPIO.output(pins[other_pin], GPIO.LOW) # Set pins to low(0V) to off led
GPIO.output(pins[pin], GPIO.HIGH) # Set pins to high(+3.3V) to on led
print(pins[pin]," Red Led is On...")
time.sleep(sleep_time)
# ---Let_led_on----------------------------------
def Let_Led_off():
GPIO.output(pins['pin_R'], GPIO.LOW) # Set pins to low(0V) to off led
time.sleep(1)
GPIO.output(pins['pin_G'], GPIO.LOW) # Set pins to low(0V) to off led
print(" Red and Green LEDs is off.")
# ---Let_led_off----------------------------------
#------------------------------------------------------------------
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('1.Socket created')
try:
s.bind((HOST, PORT))
except socket.error as msg:
print('>> Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
sys.exit()
print('2.Socket bind complete')
s.listen(10)
print('3.Socket now listening')
quit_count=0 # initial
while 1:
# wait to accept a connection - blocking call
conn, addr = s.accept()
quit_count = quit_count + 1
print('4.Connected with ' + addr[0] + ':' + str(addr[1]),',now is ',quit_count,' times connect')
welcome_str='Hello, Welcome to here..The input value must be :\r\n' \
+' r : red led on\r\n'\
+' g : green led on\r\n'\
+' o : Two leds off\r\n'\
+' q : quit the connection\r\n'
conn.sendall(welcome_str.encode())
try:
conn.settimeout(timeout_limit)
# 获得一个连接,然后开始循环处理这个连接发送的信息
while True:
try:
data = conn.recv(1024)
except IOError as rcv_msg:
print(">> Failed to recv() data.: %s: %s\n" % (rcv_msg.errno, rcv_msg.strerror))
break
buf = data.decode()
print( "<< Get value " + buf)
if buf == 'r':
print("<< Red LED is on")
conn.sendall('>> Red LED is on...\r\n'.encode())
'''
do something...
'''
Let_Led_on('pin_R')
elif buf == 'g':
print("<< Green LED is on")
conn.sendall('>> Green LED is on...\r\n'.encode())
'''
do something...
'''
Let_Led_on('pin_G')
elif buf =='o':
print("<< Two LEDs turn off.")
conn.sendall('>> Green and Red LED turn off!\r\n'.encode())
'''
do something...
'''
Let_Led_off()
elif buf =='q':
Let_Led_off()
print("<< The Connection Close")
conn.sendall('>> The Connection will Close in 3 sec, Rerun again.\r\n'.encode())
break
else:
print("<< Invalid command, try again!")
conn.sendall('>> Invalid command, pls try again!\r\n'.encode())
except socket.timeout: # 如果建立连接后,该连接在设定的时间内无数据发来,则time out
print('time out')
conn.close()
print("5.This Connection ",addr[0]," has disconnected.")
if quit_count ==connect_times_limit : # 如果q(quit),即断开连接次数达到一定次数后,将关闭socket.
break
print("6.Socket close,When quit times = ",quit_count)
s.close()
(二)客户端程序
可参考之前文章,收发数据要加一个循环,如下:
#!/usr/bin/python3
# 文件名:Socket_client_simp_test.py
# 参考:https://blog.csdn.net/qq_25406669/article/details/80576770
# 导入 socket、sys 模块
import socket
import sys
import time
# 创建 socket 对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('1.Socket created')
# 获取本地主机名
#host = socket.gethostname()
#host='localhost'
host='192.168.1.107'
# 设置端口号
port = 8888
# 连接服务,指定主机和端口
try:
print(">> This connection will connect to host:", host)
s.connect((host, port))
except IOError as e:
print(">> Failed to connect host.: %s: %s\n" % (e.errno, e.strerror))
sys.exit()
print("2.Connected with host ",host,":",port)
# 接收小于 1024 字节的数据
msg1 = s.recv(1024)
print('Server Say: ',msg1.decode('utf-8'))
while True:
in_cmd = input('please input :')
try:
s.sendall(in_cmd.encode())
srv_reply=s.recv(1024).decode()
except IOError as rcv_msg:
print("Failed to sendall() or recv() data.: %s: %s\n" % (rcv_msg.errno, rcv_msg.strerror))
break
print('Server reply : ',srv_reply)
if in_cmd=='q':
#print(in_cmd)
time.sleep(3) # wait 3 sec ,and break
break
print('The connection disconnected!')
s.close()