2021年3月8日 星期一

[Python]字串切割存入list再透過socket傳送至server端

首先先加強對Python socket的了解

Reference : https://ithelp.ithome.com.tw/articles/10205819 

socket.accept //server等待client端的連線 accept代表socket 採用阻塞式訪問


位類別名稱宣告解釋內容
familysocket.AF_UNIX於本機端進行串接
socket.AF_INET於伺服器與伺服器之間進行串接
socket.AF_INET6使用IPv6於伺服器與伺服器之間進行串接
typesocket.SOCK_STREAM使用TCP(資料流)的方式提供可靠、雙向、串流的通信頻道
socket.SOCK_DGRAM使用UDP()的方式通用的免連線訊息交換通道

Reference : https://www.itread01.com/content/1541825839.html


socket物件方法
函式 型別 描述
s.bind() 服務端用 繫結地址和埠到套接字,引數address為元組形式的(host, port)
s.listen() 服務端用 開始監聽繫結的地址埠程式(程序),引數backlog指定在拒絕連線之前,可以掛起的最大連線數量。
s.accept() 服務端用 等待客戶端的連線(阻塞式)。
s.connect() 客戶端用 主動去連線伺服器,引數address為元組形式的(host, port),如果連接出錯,返回socket.error錯誤。
s.connect_ex() 客戶端用 主動去連線伺服器,引數address為元組形式的(host, port),出錯時返回出錯碼,而不是丟擲異常。
s.recv() 公共使用 接收資料,返回位元組型字串資料,引數bufsize指定接收資料的最大長度。
s.send() 公共使用 傳送資料,返回傳送成功的位元組數,引數data是要傳送的位元組型字串資料。
s.sendall() 公共使用 完整發送資料。內部迴圈呼叫send直至資料傳送完整,引數data是要傳送的位元組型字串資料。
s.recvfrom() 公共使用 接收資料,返回值是(data, address)。data是包含接收資料的字串,address是傳送資料的套接字地址。
s.sendto() 公共使用 傳送資料,將資料傳送到套接字,address形式為(host, port)的元組,指定遠端地址。返回值是傳送位元組數。
s.close() 公共使用 關閉套接字
s.getpeername() 公共使用 返回連線套接字的遠端地址。返回值通常是元組(host, port)。
s.getsockname() 公共使用 返回套接字自己的地址。通常是一個元組(host, port)。
s.setsockopt() 公共使用 設定給定套接字選項的值。
s.getsockopt() 公共使用 返回套接字選項的值。
s.settimeout() 公共使用 設定套接字操作的超時期,timeout是一個浮點數,單位是秒。值為None表示沒有超時期。
s.gettimeout() 公共使用 返回當前超時期的值,單位是秒,如果沒有設定超時期,則返回None。
s.fileno() 公共使用 接收資料,返回位元組型字串資料,引數bufsize指定接收資料的最大長度。
s.setblocking() 公共使用 flag為0非阻塞,否則為阻塞模式(預設)。非阻塞模式調recv()或send()沒有資料,將引起socket.error異常。
s.makefile() 公共使用 建立一個與該套接字相關連的檔案。


Reference : https://www.itread01.com/content/1549100881.html

def convertRaw_and_SplitToSave(split_size):
print("[Func]splitDataAndSave")
with open(r'c:\test.jpg', 'rb') as f:
res = base64.b64encode(f.read())
print("len = " + str(len(str(res))) + " Context : " + str(res))
globals.tmp_array = re.findall('.{' + str(split_size) + '}', str(res))
globals.tmp_array.append(str(res)[(len(globals.tmp_array) * split_size):])
globals.tmp_array[0] = str(globals.tmp_array[0]).strip('b\'')
#找尋最後一筆 把'過濾掉回存 先取得長度 將陣列長度減1 strip(''') 然後回存
print("end print " + str(globals.tmp_array[0]))
另外,在轉塗作字串切割時 會有b'的特殊符號出現,必須去除
在此,參考這篇【python】去除字符串头尾的多余符号
 https://blog.csdn.net/u014636245/article/details/103120201
使用.strip('b\'')去除掉 加鞋線是因為跳脫字元'
此外針對影像串流部分:
Reference : https://www.jianshu.com/p/931cd24450ec
上傳串流部分
result, imgencode = cv2.imencode('.jpg', frame, encode_param)
        data = numpy.array(imgencode)
        stringData = data.tobytes()

        stringDataLen = str(len(stringData)).ljust(16)
        print("stringDataLength = " + stringDataLen)
        client.send(stringDataLen.encode())
        print("stringDataLen = " + stringDataLen + " Context : " + str(stringData))
        print(stringData)
        data_perform = [b'']
        data_perform = re.findall(b"[\s\S]{500}", stringData)  # 就是这里需要做小小的改造,看仔细哦
        data_perform.append(stringData[(len(data_perform) * 500):])
        #globals.tmp_array = re.findall('.{' + str(split_size) + '}', str(stringData))
        #globals.tmp_array.append(str(stringData)[(len(globals.tmp_array) * split_size):])
        print(data_perform)
        print(len(data_perform))

        for i in range(len(data_perform)):
            print(" data_perform array len = " + str(len(data_perform)) + " ,prepare to send [" + str(i) + "]:" + str(data_perform[i]))
            client.send(data_perform[i]);

        ret, frame = capture.read()# 以幀為單位獲取影象
        decimg = cv2.imdecode(data, 1)
        cv2.imshow('CLIENT', decimg)
        key = cv2.waitKey(20)

        if key == 113:  # 按q拍照, 比照ASCII碼
            cv2.imwrite("fangjian2.jpeg", frame)  # 拍照存檔檔名
            continue
        if key == 27:  # 按esc停止, 比照ASCII碼
            break
    client.close()
    cv2.destroyAllWindows()
接收串流部分
def recvall(sock, count):
    buf = b''
    while count:
        newbuf = sock.recv(count)
        if not newbuf: return None
        buf += newbuf
        count -= len(newbuf)
    return buf

length = recvall(conn, 16)
            print(length)
            stringData = recvall(conn, int(length))
            data = numpy.fromstring(stringData, dtype='uint8')
            decimg = cv2.imdecode(data, 1)
            cv2.imshow('SERVER', decimg)
            cv2.waitKey(30)
            time.sleep(1)

沒有留言:

張貼留言