2018年7月7日 星期六

一起學 Python 105 : 接收與傳送 TCP/IP (Client 連至 Server) 並將接收到的值傳到 google sheet

實現從手機開啟一個 TCP  Server ,利用電腦執行 python 程序使手機傳過來的訊息再轉傳到 Google sheet 。 Python 至 google sheet 的部分請參考 一起學 Python 102 : 使用 Google API 上傳資料至 Google sheet,程式碼如果你想直接用本文功能就用本文的就行了。因兩文之間我有修改一小部分

程式碼

import socket
import sys
import time
import datetime
import gspread
from oauth2client.service_account import ServiceAccountCredentials

SERVER_IP = "192.168.0.102" #你手機的 server IP
SERVER_PORT = 55555 #你手機的 server Port

GDOCS_OAUTH_JSON = '你的json絕對路徑' 
GDOCS_SPREADSHEET_NAME = "TCP_toSheet" #google sheet 的名稱
RESENT_TIMES = 3

## ===== Listen from TCP/IP  =====
def lisgenTCP(SERVER_IP,SERVER_PORT):
    #創建Socket,SOCK_STREAM表示類型為TCP
    print("Starting socket: TCP...")
    try:
        socket_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    except socket.error as msg:
        sys.stderr.write("[ERROR] %s\n" % msg)
        sys.exit(1)        

    #向伺服器發出連接請求,需要指定伺服器IP和埠(失敗延時五秒重連)
    Connected = 0
    while not Connected:
        try :    
            print("Connecting to server @ %s:%d..." %(SERVER_IP, SERVER_PORT))
            server_addr = (SERVER_IP, SERVER_PORT)
            socket_tcp.connect(server_addr)
            Connected = 1
            print("Connect successfully [ %s ]" % ( time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
            H_message = 'Evan is here.\r\n' 
            socket_tcp.send( H_message.encode(encoding='utf_8', errors='strict') ) #發送訊息到 server
        except socket.error as msg:
            sys.stderr.write("[ERROR] %s\n" % msg)
            time.sleep(5)
    
    #接收伺服器發來的數據
    while 1:
        data = socket_tcp.recv(1024).decode(encoding='utf_8', errors='strict')
        print("Receive : '%s'" % data)
        if data != None:
            return data
        
    #print("Disconnecting to server @ %s:%d..." %(SERVER_IP, SERVER_PORT))
    #socket_tcp.close
## =====================================


## ===== Send data to Google Sheet =====

## =====================================

def login_open_sheet(oauth_key_file, spreadsheet):
    """Connect to Google Docs spreadsheet and return the first worksheet."""
    try:
        scope =  ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive']
        credentials = ServiceAccountCredentials.from_json_keyfile_name(oauth_key_file, scope)
        gc = gspread.authorize(credentials)
        worksheet = gc.open(spreadsheet).sheet1
        return worksheet
    except Exception as ex:
        print('Unable to login and get spreadsheet.')
        print('Google sheet login failed with error:', ex)
        sys.exit(1)

worksheet = None

def sentMessageToSheet(message,worksheet):
    for i in range(0,RESENT_TIMES):
        LOGININ = 0
        while not LOGININ:
            # Login if necessary.
            if worksheet is None:
                worksheet = login_open_sheet(GDOCS_OAUTH_JSON, GDOCS_SPREADSHEET_NAME)
            try:            
                worksheet.update_acell('A1',message)
                LOGININ = 1
            except:
                print('Error, logging in again')
                worksheet = None
                continue

        print('Upate')
        time.sleep(0.8)

## ===== MAIN =====
while 1:
    text = lisgenTCP(SERVER_IP,SERVER_PORT)
    sentMessageToSheet(text,worksheet)



執行結果

1. 手機下載 APP(隨意) 並開啟 TCP SERVER



2. 執行 python


3. 手機收到來自 Python (PC端Client)的訊息


4. 手機傳送訊息至 Python (出現第二次 "Evan is here." 表示 Python 已經把資料傳上去 Google sheet 並且重新連結上 TCP Server)



5. Google Sheet 的儲存格也改變 ( 且重連上 TCP Server )


6. 再次發送不同的文字





參考連結
[Python] Simple Socket Server
send 函数 报错:TypeError: a bytes-like object is required, not 'str'