Python套接字侦听

发布于 2021-01-29 15:21:57

下面提到的所有内容都在使用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
被浏览
41
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    玩了一段时间后,终于可以使用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()
    

    客户端看不到其他客户端说的话,来自服务器的消息将被发送到所有客户端。我将其留给读者练习。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看