【发布时间】:2015-08-13 08:13:11
【问题描述】:
这个问题有两个方面。
1. 所以我需要为一个在 another.py 中定义和创建的套接字服务器运行代码,在 PyCharm 上单击运行就可以了,但如果你 exec() 文件它只是运行代码的底部。
这里有一些答案,但它们是相互冲突的,并且适用于 Python 2。
据我所知,有三种方式:
- Execfile(),我认为是 Python 2 代码。
- os.system()(但我看到有人说为此传递给操作系统是不正确的)
-还有subprocess.Popen(也不知道怎么用)
我需要它在后台运行,它用于为整个程序的 recv 部分创建套接字线程并侦听这些端口,以便我可以向路由器输入命令。
这是有问题的完整代码:
import sys
import socket
import threading
import time
QUIT = False
class ClientThread(threading.Thread): # Class that implements the client threads in this server
def __init__(self, client_sock): # Initialize the object, save the socket that this thread will use.
threading.Thread.__init__(self)
self.client = client_sock
def run(self): # Thread's main loop. Once this function returns, the thread is finished and dies.
global QUIT # Need to declare QUIT as global, since the method can change it
done = False
cmd = self.readline() # Read data from the socket and process it
while not done:
if 'quit' == cmd:
self.writeline('Ok, bye. Server shut down')
QUIT = True
done = True
elif 'bye' == cmd:
self.writeline('Ok, bye. Thread closed')
done = True
else:
self.writeline(self.name)
cmd = self.readline()
self.client.close() # Make sure socket is closed when we're done with it
return
def readline(self): # Helper function, read up to 1024 chars from the socket, and returns them as a string
result = self.client.recv(1024)
if result is not None: # All letters in lower case and without and end of line markers
result = result.strip().lower().decode('ascii')
return result
def writeline(self, text): # Helper func, writes the given string to the socket with and end of line marker at end
self.client.send(text.strip().encode("ascii") + b'\n')
class Server: # Server class. Opens up a socket and listens for incoming connections.
def __init__(self): # Every time a new connection arrives, new thread object is created and
self.sock = None # defers the processing of the connection to it
self.thread_list = []
def run(self): # Server main loop: Creates the server (incoming) socket, listens > creates thread to handle it
all_good = False
try_count = 0 # Attempt to open the socket
while not all_good:
if 3 < try_count: # Tried more than 3 times without success, maybe post is in use by another program
sys.exit(1)
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Create the socket
port = 80
self.sock.bind(('127.0.0.1', port)) # Bind to the interface and port we want to listen on
self.sock.listen(5)
all_good = True
break
except socket.error:
print('Socket connection error... Waiting 10 seconds to retry.')
del self.sock
time.sleep(10)
try_count += 1
print('Server is listening for incoming connections.')
print('Try to connect through the command line with:')
print('telnet localhost 80')
print('and then type whatever you want.')
print()
print("typing 'bye' finishes the thread. but not the server",)
print("eg. you can quit telnet, run it again and get a different ",)
print("thread name")
print("typing 'quit' finishes the server")
try:
while not QUIT:
try:
self.sock.settimeout(0.500)
client = self.sock.accept()[0]
except socket.timeout:
time.sleep(1)
if QUIT:
print('Received quit command. Shutting down...')
break
continue
new_thread = ClientThread(client)
print('Incoming Connection. Started thread ',)
print(new_thread.getName())
self.thread_list.append(new_thread)
new_thread.start()
for thread in self.thread_list:
if not thread.isAlive():
self.thread_list.remove(thread)
thread.join()
except KeyboardInterrupt:
print('Ctrl+C pressed... Shutting Down')
except Exception as err:
print('Exception caught: %s\nClosing...' % err)
for thread in self.thread_list:
thread.join(1.0)
self.sock.close()
if "__main__" == __name__:
server = Server()
server.run()
print('Terminated')
注意事项:
这是在 Python 3.4 中创建的
我使用 Pycharm 作为我的 IDE。
整体的一部分。
2. 所以我正在创建一个闪电检测系统,这就是我希望它完成的方式:
- 永远监听路由器上的端口
上面已经完成了,但是问题1中描述了这个问题。
- 从文本文件中提取号码以发送短信
这也完成了。
- 发送 http get / post 到路由器上的端口
问题在于,如果我以二进制形式发送它,我不确定路由器将如何操作,我怀疑这无关紧要,通过 GSM 发送的输入命令是特定的。在某些时候可能需要进行一些澄清。
- 接收路由器回复和异常管理
- 收听继电器跳闸以在严重或接近罢工警告时发出警报。
- 如果跳闸,从文本文件向存储中的手机发送消息
这将是发送的 http get / post。
- 等待路由器回复表明消息已发送,如果不是则异常处理
-返回开始
有一些问题我想了解一些背景知识,这些问题证明很难通过旧版 Google 找到,这里是堆栈中的答案。
如何从另一个文件中运行的另一个进程中获取来自路由器的接收数据?我想我可以写入一个文本文件并调用该数据,但我宁愿不这样做。
如何进行多进程以及使用哪种方法。
如何将http get / post发送到路由器上的socket,根据路由器手册需要的post如下:e.g.
"http://192.168.1.1/cgi-bin/sms_send?number=0037061212345&text=test"
注意事项:在 Python 3.4/Pycharm IDE 上使用套接字、线程、系统和时间。
使用的雷电探测器是 LD-250,带有 RLO 继电器。
使用 RUT500 Teltonica 路由器。
任何方向/cmets,发现的错误,任何我严重缺失的东西都将不胜感激!非常感谢您:D 非常鼓励建设性的批评!
【问题讨论】:
标签: multithreading sockets python-3.x