Очень плохо знаком с кодированием . У меня есть эти два скрипта Python. Одним из них является сервер , а другим - GUI , который также выступает в качестве клиента (потому что я не знал, как подключить их в противном случае, так как мне нужно было отправлять данные, полученные от GUI к серверу). В цикле while вы можете видеть, что я получаю сообщения от всех трех соединений.
пользователь 1 подключен
пользователь 2 - conn1
Графический интерфейс conn2
но и от пользователя 1, и от пользователя 2 они отправляют по одному сообщению каждое (, то есть дБА, проходящий через микрофон в данный момент ). Но для графического интерфейса он отправляет три сообщения ( Audio-Threshold, индекс первого микрофона, индекс второго микрофона ), которые мне нужно получить на стороне сервера. Но этот способ, показанный на сервере, похоже, не работает, так как я получаю эти сообщения, но каждый раз, когда запускаю код, в странной / иной схеме.
Сторона сервера:
import socket
import requests
import os
PARAMS = {'Function': "Cut",
"Duration": 300, # First Camera
"Input": 1}
PARAMS2 = {'Function': "Cut",
"Duration": 300, # Second Camera
"Input": 2}
PARAMS3 = {'Function': "Cut",
"Duration": 300, # Overview Camera
"Input": 3}
# VMix's API Endpoint - Requests are made to this API
URL_ENDPOINT = "http://127.0.0.1:8088/api/"
CLIENT1 = "Client 1"
CLIENT2 = "Client 2"
TH = "Threshold"
INDEX1 = "INDEX1"
INDEX2 = "INDEX2"
# Socket creation
s = socket.socket() # Creates a socket
host = socket.gethostname()
port = 50200
print("Socket Created...")
s.bind((host, port))
print("Socket Bound...")
s.listen()
print("Waiting for connections...")
print(26 * '-')
# GUI client
conn2, addr2 = s.accept()
print(f"☑ GUI with IP: {addr2} has connected...")
# Setup the connection for the first client
conn, addr = s.accept()
print(f"☑ Client with address {addr} has connected...")
# Connection setup for the second client
conn1, addr1 = s.accept()
print(f"☑ Client with address {addr} has connected...")
print(26 * '-')
print("Recieving audio")
while True:
print("{:15}{:15}{:15}{:15}{}".format(CLIENT1, CLIENT2, TH, INDEX1, INDEX2))
while 1:
recv_message, recv_message1, recv_message2 = conn.recv(128), conn1.recv(128), conn2.recv(1024)
recv_index, recv_index1 = conn2.recv(1024), conn2.recv(1024)
print("{:18}{:18}{:18}{:18}{}".format(recv_message.decode(
"utf-8"), recv_message1.decode("utf-8"), recv_message2.decode("utf-8"),
recv_index.decode("utf-8"), recv_index1.decode("utf-8")))
threshold = recv_message2
db, db1, threshold = int(recv_message), int(recv_message1), int(threshold)
if (db > threshold) and (db > db1):
response = requests.get(url=URL_ENDPOINT, params=PARAMS)
elif (db1 > threshold) and (db1 > db):
response = requests.get(url=URL_ENDPOINT, params=PARAMS2)
else:
response = requests.get(url=URL_ENDPOINT, params=PARAMS3)
GUI Side:
import tkinter as tk
from tkinter import *
from tkinter import ttk
import subprocess
import requests
import socket
import struct
import os
import time
from threading import *
try:
import pyaudio
except ImportError:
os = struct.calcsize("P") * 8
if(os == 32):
url = 'https://kenan0x0.github.io/Project-PAD/week3/PyAudio-0.2.11-cp37-cp37m-win32.whl'
local_filename = url.split('/')[-1]
r = requests.get(url, allow_redirects=True)
open(local_filename, 'wb').write(r.content)
subprocess.call(["pip", "install", local_filename], shell=False)
subprocess.call(
["python", "-m", "pip", "install", "pyaudio"], shell=False)
else:
url1 = 'https://kenan0x0.github.io/Project-PAD/week3/PyAudio-0.2.11-cp37-cp37m-win_amd64.whl'
local_filename1 = url1.split('/')[-1]
r1 = requests.get(url1, allow_redirects=True)
open(local_filename1, 'wb').write(r1.content)
subprocess.call(["pip", "install", local_filename1], shell=False)
subprocess.call(
["python", "-m", "pip", "install", "pyaudio"], shell=False)
s = socket.socket()
host = socket.gethostname()
port = 50200
s.connect((host, port))
# Main window
window = tk.Tk()
window.geometry("650x600")
window.title("Black Magic Switcher")
window.iconbitmap(r'./Iconshock-Disc-Jockey-Mixer.ico')
# Threads so functions can be called simultaneously
def cliThread():
Thread(target=runClient).start()
def klaThread():
Thread(target=runClient2).start()
def devThread():
Thread(target=showDevi).start()
# ------------------ End Threads ----------------------
# Functions that perform a task
def showTH():
# while True:
# s.send(val.encode("utf-8"))
# time.sleep(0.2)
# window.update()
while True:
threshold = ThresholdEntry.get()
threshold = str(threshold)
s.send(threshold.encode("utf-8"))
time.sleep(0.2)
window.update()
# Runs Client 1
def runClient():
os.system("python client.py")
# Runs Client 2
def runClient2():
os.system("python klant.py")
# Prints entry values first mic
def showEntry():
index = firstMicEntry.get()
index = str(index)
s.send(index.encode("utf-8"))
# Prints entry values second mic
def showEntry1():
index = secondMicEntry.get()
index = str(index)
s.send(index.encode("utf-8"))
# Shows connected input devices
def showDevi():
p = pyaudio.PyAudio()
info = p.get_host_api_info_by_index(0)
numdevices = info.get('deviceCount')
for i in range(0, numdevices):
if (p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0:
lbl = tk.Label(text=("Input Device id ", i, " - ",
p.get_device_info_by_host_api_device_index(0, i).get('name')))
lbl.pack()
def killServer():
os.system("taskkill /f /im py.exe")
# ----------------------- End Functions -----------------------------
# Title of the program
h1 = tk.Label(text="User GUI | Black Magic", font=("Kreon", 25))
h1.pack()
bk1 = ttk.Separator(window, orient="horizontal")
bk1.pack(fill="x", pady=5)
# Threshold
h2 = tk.Label(text="Audio-Threshold: ⤵", font=("Kreon", 15))
h2.pack()
# scale = tk.Scale(window, from_=0, to=100, command=showTH,
# orient="horizontal", length=400, cursor="fleur")
# scale.set(44)
# scale.pack(pady=3)
ThresholdEntry = tk.Entry(width=20, justify="center", bd=3)
ThresholdEntry.pack(pady=3)
sendTH = tk.Button(text="Input Threshold", activebackground="black",
activeforeground="white", cursor="hand2", relief="raised", command=showTH)
sendTH.pack(pady=3)
# Devices listing Button
devbut = tk.Button(text="Show Available Mics", activebackground="black",
activeforeground="white", cursor="hand2", relief="raised",
command=devThread)
devbut.pack(pady=3)
# Label change first mic
firstMic = tk.Label(text="Insert First Mic Index ⤵: ")
firstMic.pack(pady=3)
firstMicEntry = tk.Entry(width=20, justify="center", bd=3)
firstMicEntry.pack(pady=3)
sendMicIndex = tk.Button(text="Send First Index", activebackground="black",
activeforeground="white", cursor="hand2", relief="raised", command=showEntry)
sendMicIndex.pack(pady=3)
# Client 1 Button
clibut = tk.Button(text="Run First Client", activebackground="black",
activeforeground="white", cursor="hand2", relief="raised", command=cliThread)
clibut.pack(pady=3)
# Label change second mic
secondMic = tk.Label(text="Insert Second Mic Index ⤵: ")
secondMic.pack(pady=3)
secondMicEntry = tk.Entry(width=20, justify="center", bd=3)
secondMicEntry.pack(pady=3)
sendMicIndex1 = tk.Button(text="Send Second Index", activebackground="black",
activeforeground="white", cursor="hand2", relief="raised", command=showEntry1)
sendMicIndex1.pack(pady=3)
# Client 2 Button
klabut = tk.Button(text="Run Second Client", activebackground="black",
activeforeground="white", cursor="hand2", relief="raised", command=klaThread)
klabut.pack(pady=3)
exitBut = tk.Button(text="Stop Program", activebackground="black",
activeforeground="white", cursor="hand2", relief="raised", command=killServer)
exitBut.pack(pady=3)
window.mainloop()
После всего этого кода мой вопрос. Возможно ли для клиента использовать несколько операторов socket.send()
, а для сервера - получать их с одинаковым количеством операторов connection.recv()
в правильном порядке.
Я знаю, что есть миллион вещей, которые нужно улучшить в этом коде, но для кода новичка он делает то, что мне нужно, за исключением этих нескольких посылок. Если у вас есть другие примечания к коду, пожалуйста, поделитесь ими.