我正在嘗試為關鍵字抓取非常忙碌的抽搐聊天,但有時套接字會停止一瞬間,但在那一瞬間,5 條訊息可以通過。我想實作一些多執行緒,但在下面的代碼中沒有運氣。似乎他們都沒有抓住一個關鍵字,或者都成功了。任何幫助表示贊賞。代碼如下:
import os
import time
from dotenv import load_dotenv
import socket
import logging
from emoji import demojize
import threading
# loading environment variables
load_dotenv()
# variables for socket
server = "irc.chat.twitch.tv"
port = 6667
nickname = "frankied003"
token = os.getenv("TWITCH_TOKEN")
channel = "#xqcow"
# creating the socket and connecting
sock = socket.socket()
sock.connect((server, port))
sock.send(f"PASS {token}\n".encode("utf-8"))
sock.send(f"NICK {nickname}\n".encode("utf-8"))
sock.send(f"JOIN {channel}\n".encode("utf-8"))
while True:
consoleInput = input(
"Enter correct answer to the question (use a ',' for multiple answers):"
)
# if console input is stop, the code will stop ofcourse lol
if consoleInput == "stop":
break
# make array of all the correct answers
correctAnswers = consoleInput.split(",")
correctAnswers = [answer.strip().lower() for answer in correctAnswers]
def threadingFunction():
correctAnswerFound = False
# while the correct answer is not found, the chats will keep on printing
while correctAnswerFound is not True:
while True:
try:
resp = sock.recv(2048).decode(
"utf-8"
) # sometimes this fails, hence retry until it succeeds
except:
continue
break
if resp.startswith("PING"):
sock.send("PONG\n".encode("utf-8"))
elif len(resp) > 0:
username = resp.split(":")[1].split("!")[0]
message = resp.split(":")[2]
strippedMessage = " ".join(message.split())
# once the answer is found, the chats will stop, correct answer is highlighted in green, and onto next question
if str(strippedMessage).lower() in correctAnswers:
print(bcolors.OKGREEN username " - " message bcolors.ENDC)
correctAnswerFound = True
else:
if username == nickname:
print(bcolors.OKCYAN username " - " message bcolors.ENDC)
# else:
# print(username " - " message)
t1 = threading.Thread(target=threadingFunction)
t2 = threading.Thread(target=threadingFunction)
t3 = threading.Thread(target=threadingFunction)
t1.start()
time.sleep(.3)
t2.start()
time.sleep(.3)
t3.start()
time.sleep(.3)
t1.join()
t2.join()
t3.join()
uj5u.com熱心網友回復:
首先,讓 3 個執行緒在同一個套接字上并行讀取沒有多大意義,它只會導致混亂和競爭條件。
但是,主要問題是您假設recv單個訊息將始終讀取單個訊息。但這不是 TCP 的作業方式。TCP 沒有訊息的概念,只是一個位元組流。訊息是應用程式級別的概念。單recv可能包含一個訊息,多條訊息,訊息的部分...
所以你必須根據應用協議定義的語意來真正決議你得到的資料,即
- 初始化一些緩沖區
- 從套接字獲取一些資料并將它們添加到緩沖區 - 不要解碼資料
- 從緩沖區中提取所有完整訊息,分別解碼和處理每個訊息
- 將剩余的不完整訊息留在緩沖區中
- 繼續#2
除此之外不要在recv(..).decode(..). 鑒于您使用的是阻塞套接字,recv通常只有在連接出現致命問題時才會失敗,在這種情況下,重試將無濟于事。問題很可能是因為您正在呼叫decode不完整的訊息,這也可能意味著 utf-8 編碼無效。但是,由于您只是忽略了問題,因此您基本上會丟失訊息。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/366709.html
