STUN服务器是什么?
https://www.3cx.com/pbx/what-is-a-stun-server/
A STUN (Session Traversal of User Datagram Protocol [UDP] Through Network Address Translators [NATs]) server allows NAT clients (i.e. IP Phones behind a firewall) to set up phone calls to a VoIP provider hosted outside of the local network.
STUN Server Diagram
The STUN server allows clients to find out their public address, the type of NAT they are behind and the Internet side port associated by the NAT with a particular local port. This information is used to set up UDP communication between the client and the VoIP provider to establish a call. The STUN protocol is defined in RFC 3489.
The STUN server is contacted on UDP port 3478, however, the server will hint clients to perform tests on alternate IP and port number too (STUN servers have two IP addresses). The RFC states that this port and IP are arbitrary.
Stun functionality is seamlessly handled by 3CX - an easy to install PBX.
中文解释:
https://mp.weixin.qq.com/s/cQgli4y-sLNg918MKW8D0g
说人话就是:
白嫖公开的STUN服务器,用它的UDP端口,走流量,打洞。
内网机器往 stun4.l.google.com(142.251.2.127) 发送了一个 STUN Binding 的包,这是通过 UDP 传输的,所以这个请求会在运营商里面打开一个临时的 UDP 通道。
内网机器就是通过这个 临时的 UDP 通道 跟 STUN 服务器通信。所以这个 UDP 通道的信息,STUN 服务器是知道的。因此 STUN 服务器可以把这个 UDP 通道信息 放在 STUN Response 里面返回给 内网的机器。
PYTHON处理带引号的文本
3918,唐僧,183,NULL,,
3919,"孙悟空,猪八戒",176,NULL,,
如果用split(","),是会出错的。两种办法
1,
import csv
from io import StringIO
line = '3919,"孙悟空,猪八戒",176,NULL,,'
# 将文本包装在 StringIO 对象中,以便 csv 模块可以处理字符串
csv_data = StringIO(line)
# 创建 csv 读取器
reader = csv.reader(csv_data)
# 读取一行数据
result = next(reader)
print(result)
2,
import re
line = '3919,"孙悟空,猪八戒",176,NULL,,'
# 定义正则表达式模式,匹配双引号内的内容或者逗号分隔的内容
pattern = re.compile(r'("(?:[^"]|"")*"|[^,]*)')
# 使用 findall() 方法查找匹配的内容,并去除双引号
result = [m.strip('"') for m in pattern.findall(line)]
print(result)
Python录音的代码
import pyaudio
import wave
import threading
import time
class Recorder:
def __init__(self, filename='recording.wav', chunk=1024, format=pyaudio.paInt16, channels=2, rate=44100):
self.filename = filename
self.chunk = chunk
self.format = format
self.channels = channels
self.rate = rate
self.frames = []
self.p = pyaudio.PyAudio()
self.is_recording = False
self.record_thread = None
def start_recording(self):
if self.is_recording:
print("Recording is already in progress.")
return
print("Recording started.")
self.is_recording = True
self.frames = []
self.stream = self.p.open(format=self.format,
channels=self.channels,
rate=self.rate,
input=True,
frames_per_buffer=self.chunk)
self.record_thread = threading.Thread(target=self._record)
self.record_thread.start()
def stop_recording(self):
if not self.is_recording:
print("No recording in progress.")
return
print("Recording stopped.")
self.is_recording = False
self.stream.stop_stream()
self.stream.close()
self.record_thread.join()
wf = wave.open(self.filename, 'wb')
wf.setnchannels(self.channels)
wf.setsampwidth(self.p.get_sample_size(self.format))
wf.setframerate(self.rate)
wf.writeframes(b''.join(self.frames))
wf.close()
def _record(self):
while self.is_recording:
data = self.stream.read(self.chunk)
self.frames.append(data)
if __name__ == "__main__":
filename = input("Enter the filename to save recording (default is 'recording.wav'): ").strip() or 'recording.wav'
recorder = Recorder(filename=filename)
print("Press 'r' to start recording, 's' to stop recording, and 'q' to quit.")
while True:
command = input("> ").strip().lower()
if command == 'r':
recorder.start_recording()
elif command == 's':
recorder.stop_recording()
print("Recording saved to", filename)
elif command == 'q':
if recorder.is_recording:
recorder.stop_recording()
print("Recording saved to", filename)
break
else:
print("Invalid command. Please enter 'r' to start recording, 's' to stop recording, or 'q' to quit.")
time.sleep(0.1) # sleep to avoid high CPU usage in the loop
VSCODE 正则替换
中文姓名:
([\u4E00-\u9FA5]{2,3})
$1
身份证号:
([0-9xX]{18})\n
$1