多线程套接字在远程脚本执行之前关闭

时间:2017-11-07 08:31:41

标签: python

使用Python 2.6.6,我无法从客户端脚本获取完整数据,因为在客户端脚本执行结束之前怀疑套接字被关闭,而如果我手动触发远程服务器上的脚本,客户端脚本工作正常

什么脚本 -

触发SCRIPT

仅传输客户端脚本[agent.py]并使用多线程远程触发。

客户端脚本

  • agent.py将被转移到目标服务器[1000 +]
  • 在(1000+)远程服务器[linux]上运行以收集数据并返回 从每台远程计算机返回到服务器
  • 的字典列表

服务器脚本

  • 接收数据并转换为CSV

客户端脚本 - agent.py

 s = socket.socket()             # Create a socket object
 host = "<SERVER_HOST>"          # server ip
 port = 12345                    # Reserve a port for your service.
 try:
    s.connect((host, port))
    instlist = []
    infoCollect = processInfo()  #get the info in dictionary object
    instlist.append(infoCollect)
    data_string = str(instlist)
    s.sendall(data_string)
    s.send(",")
    s.shutdown(socket.SHUT_WR)
    print('Sent ',(instlist))
    s.close()

服务器脚本[DataCollector]:

class ThreadedServer(object):
    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sock.bind((self.host, self.port))

    def listen(self):
        self.sock.listen(5)
        print 'Started Listening....'
        while True:
            client, address = self.sock.accept()
            print 'Got connection from', address
            client.settimeout(60)
            threading.Thread(target = self.listenToClient,args = (client,address)).start()

    def listenToClient(self, client, address):
        size = 1024
        while True:
           try:
              l = client.recv(size)
              while (l):
                 print ("Receiving...%s" % l)
                 f.write(l)
                 l = client.recv(size)
                 print "Instance Details Recieved"
              client.send('Thank you for connecting')

           except:
                client.close()
                return False

if __name__ == "__main__":
    while True:
        port_num = input("Port? ")
        try:
            port_num = int(port_num)
            break
        except ValueError:
            pass
    f = open(array_data,'wb')
    ThreadedServer('',port_num).listen()

触发脚本 - 此脚本的目的是启动此全部过程并将客户端脚本[agentScript]放置在1000多台服务器上并远程执行

 cmd = "python agent.py"

 takeLock = threading.Lock()

 def worker(host):
     ssh = paramiko.SSHClient() # Initiate SSH Object
     ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
     try:
        ssh.connect(host, username='user', password='pass' )

        sftp = ssh.open_sftp()   #sedning files to parellaly to all listed servers
        sftp.put(__file__, 'excludelist')
        sftp.close()

        stdin, stdout, stderr = ssh.exec_command(cmd)
        while not stdout.channel.exit_status_ready():
           # Print Only data when available
           if stdout.channel.recv_ready():
              alldata = stdout.channel.recv(1024)
              prevdata = b"1"
              while prevdata:
                prevdata = stdout.channel.recv(1024)
                alldata += prevdata
                print alldata
              return (str(alldata))
        ssh.close()

     except socket.error, v:
           print "Connection Refused"

 def main():

     with open('IPlist.txt') as ip:
         hosts = ip.read().splitlines()

     threads = []
     for h in hosts:
         t = threading.Thread(target=worker, args=(h,))
         t.start()
         threads.append(t)
     for t in threads:
         t.join()

 if __name__ == "__main__":
     main()
  

注意:客户端脚本[agent.py]需要1-5秒取决于服务器   配置以生成输出和返回值

问题 - 在服务器端填充的不完整数据,如 -

当我在远程机器上手动触发脚本进行测试时,发送完整的字典对象,如[{commonServerData},{a,b,c,d},{Engine02Data},{tempData,tempData02}]等服务器重现数据

当使用触发器脚本调用agent.py时,它会发送不完整的数据,如: 所有1000多个摊贩的[{commonServerData},{a,b,c,d}]。

我怀疑我的触发器脚本有问题,甚至在agent.py完成之前就会关闭远程服务器的套接字会话。

1 个答案:

答案 0 :(得分:0)

删除了额外的逗号s.send(',')并将其从客户端脚本添加到s.sendall(data_string + ',')执行预期的工作 -

s = socket.socket()             # Create a socket object
 host = "<SERVER_HOST>"          # server ip
 port = 12345                    # Reserve a port for your service.
 try:
    s.connect((host, port))
    instlist = []
    infoCollect = processInfo()  #get the info in dictionary object
    instlist.append(infoCollect)
    data_string = str(instlist)
    s.sendall(data_string + ',')
    s.shutdown(socket.SHUT_WR)
    print('Sent ',(instlist))
    s.close()