下面提到的所有内容都是在使用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)
如果您需要更多信息,请告诉我,任何帮助将不胜感激,我对此非常陌生并渴望学习。
答案 0 :(得分:13)
在这一段时间内玩这个终于让它在本地使用python 2.7进行telnet会话时效果很好。
它的作用是设置一个在客户端连接监听客户端内容时运行的线程。
当客户端发送一个返回(“\ r \ n”可能必须在您与Linux系统进行交互时进行更改?)时,该消息将被打印到服务器,而如果在该服务器上有原始输入,则会发生这种情况。服务器端这将被发送到客户端:
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()
客户端无法看到其他客户端说的内容,来自服务器的消息将被发送到所有客户端。我将把它作为读者的练习。
答案 1 :(得分:5)
如果你现在在Python 3中仍然想知道套接字,那么这是使用它们的基本方法:
<强> server.py 强>
import time
import socket
# creating a socket object
s = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
# get local Host machine name
host = socket.gethostname() # or just use (host == '')
port = 9999
# bind to pot
s.bind((host, port))
# Que up to 5 requests
s.listen(5)
while True:
# establish connection
clientSocket, addr = s.accept()
print("got a connection from %s" % str(addr))
currentTime = time.ctime(time.time()) + "\r\n"
clientSocket.send(currentTime.encode('ascii'))
clientSocket.close()
<强> client.py 强>
import socket
# creates socket object
s = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
host = socket.gethostname() # or just use (host = '')
port = 9999
s.connect((host, port))
tm = s.recv(1024) # msg can only be 1024 bytes long
s.close()
print("the time we got from the server is %s" % tm.decode('ascii'))
首先运行server.py,然后运行client.py
这只是接收并发送当前时间。
Python 3.4套接字的新功能
python 2.7套接字和python 3.4套接字之间的主要区别是发送消息。你必须.encode()
(通常使用&#39; ascii&#39;或空白作为参数/参数)
然后使用.decode()
例如,使用.encode()
发送,并使用.decode()
接收。