Python套接字侦听
下面提到的所有内容都在使用python 2.7的Windows计算机上
你好,
我目前正在尝试在套接字上侦听远程程序发送的数据。然后将这些数据打印到屏幕上,并请求用户输入,然后将其返回到远程程序。在测试中,我能够使远程程序向我发送命令行程序菜单(cmd,ipconfig,whoami,ftp),然后我的程序返回一个带有数字的菜单选项。
远程程序收到我的响应,然后发送所选命令的输出。ipconfig和whoami可以完美地工作,但是cmd和ftp仅返回终端的输出一次。(即,我可以在FTP程序中输入一个命令,然后在我再也听不到之前发送该命令到远程程序)
我的代码中失败的部分是, if ready[0]:
在第一次对话之后,第二次再也没有准备就绪。
我知道远程程序运行正常,因为我可以使用netcat代替我的代码,并无限期地操作cmd终端。
我该如何正确实现可解决此类连接的python套接字侦听器?
我的“程序”全部是:
import socket, sys, struct, time, select
host = ''
port = 50000
connectionSevered=0
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print 'Failed to create socket'
sys.exit()
print '[+] Listening for connections on port '+str(port)+'.'
s.bind((host,port))
s.listen(5)
def recvall(the_socket,timeout=2):
global connectionSevered
data=''; # Data found by recv
total_data=[]; # Finally list of everything
s.setblocking(0) #make socket non blocking
begin=time.time() #beginning time
while 1:
ready = select.select([client], [], [], .2)
if time.time()-begin > timeout:
print 'Timeout reached'
#Leave loop, timer has reached its threshold
break
if ready[0]:
print 'In ready loop!'
try:
data = client.recv(4096) #attempt to fetch data
if data:
begin=time.time() #reset timeout timer
total_data.append(data)
data='';
except socket.error:
print '[+] Lost connection to client. Printing buffer...'
connectionSevered=1 # Let main loop know connection has errored
pass
time.sleep(1)
#join all parts to make final string
return ''.join(total_data)
client, address = s.accept()
print '[+] Client connected!'
while (connectionSevered==0): # While connection hasn't errored
print "connectionSevered="+str(connectionSevered) # DEBUG
recvall(s)
response = raw_input() #take user input
client.sendto(response) #send input
client.close(0)
如果您需要更多信息,请告诉我,我们将不胜感激,对此我非常陌生,渴望学习。
-
玩了一段时间后,终于可以使用python 2.7在本地进行telnet会话了。
它的作用是建立一个线程,该线程在客户端连接侦听客户端内容时运行。
当客户端发送返回消息时(如果您与Linux系统交互,“ \ r \
n”可能必须更改该消息?),该消息被打印到服务器,而如果在服务器端有原始输入,则会发生这种情况。将发送给客户:import socket import threading host = '' port = 50000 connectionSevered=0 class client(threading.Thread): def __init__(self, conn): super(client, self).__init__() self.conn = conn self.data = "" def run(self): while True: self.data = self.data + self.conn.recv(1024) if self.data.endswith(u"\r\n"): print self.data self.data = "" def send_msg(self,msg): self.conn.send(msg) def close(self): self.conn.close() try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((host,port)) s.listen(5) except socket.error: print 'Failed to create socket' sys.exit() print '[+] Listening for connections on port: {0}'.format(port) conn, address = s.accept() c = client(conn) c.start() print '[+] Client connected: {0}'.format(address[0]) c.send_msg(u"\r\n") print "connectionSevered:{0}".format(connectionSevered) while (connectionSevered==0): try: response = raw_input() c.send_msg(response + u"\r\n") except: c.close()
以上答案仅适用于单个连接。我通过添加另一个用于连接的线程来更新它。现在,可以有多个用户连接。
import socket import threading import sys host = '' port = 50000 class client(threading.Thread): def __init__(self, conn): super(client, self).__init__() self.conn = conn self.data = "" def run(self): while True: self.data = self.data + self.conn.recv(1024) if self.data.endswith(u"\r\n"): print self.data self.data = "" def send_msg(self,msg): self.conn.send(msg) def close(self): self.conn.close() class connectionThread(threading.Thread): def __init__(self, host, port): super(connectionThread, self).__init__() try: self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.s.bind((host,port)) self.s.listen(5) except socket.error: print 'Failed to create socket' sys.exit() self.clients = [] def run(self): while True: conn, address = self.s.accept() c = client(conn) c.start() c.send_msg(u"\r\n") self.clients.append(c) print '[+] Client connected: {0}'.format(address[0]) def main(): get_conns = connectionThread(host, port) get_conns.start() while True: try: response = raw_input() for c in get_conns.clients: c.send_msg(response + u"\r\n") except KeyboardInterrupt: sys.exit() if __name__ == '__main__': main()
客户端看不到其他客户端说的话,来自服务器的消息将被发送到所有客户端。我将其留给读者练习。