【问题标题】:socket implement in the thread线程中的socket实现
【发布时间】:2017-08-23 12:14:53
【问题描述】:

我必须从数据库中读取一些数据并从 tcp 套接字发送 所以我从数据库中获取数据

    #main
    while True:
        cursor.execute("UPDATE `raw` SET `zombie`='"+zombieId+"' WHERE result='pending' AND protocol='tcp' AND zombie='0' LIMIT 1;")
#       time.sleep(0.2)
        cursor.execute("select * from raw WHERE `result`='pending' AND `protocol`='tcp' and `zombie`='"+zombieId+"' limit 1;")

            if cursor.rowcount>0 :
                    waitedSig = cursor.fetchone()
                    time.sleep(0.2)
                    t = threading.Thread(target=sendData , args=((waitedSig),))
                    t.start()
                    time.sleep(0.6)
            else:
                    time.sleep(1)

在线程上我将向目标发送数据

    def sendData(sig):
        timedata = datetime.datetime.fromtimestamp(int(sig[16]))
        devimei = sig[23]
        devdate = timedata.strftime("%d%m%y")
        devtime = timedata.strftime("%H%M%S")
        lat= format(sig[2])
        lon= format(sig[3])
        satcount = format(sig[5])
        speed = format(sig[4])
        batery = format(sig[7])
        if sig[9]>1000:
                band='00'
        elif sig[9]>850:
                band='02'
        else:
                band='01'
        hdop  = format(sig[10])
        gsmQ =  format(sig[6])
        lac =  format(sig[12])
        cid =  format(sig[13])
str='$MGV002,'+devimei+',12345,S,'+devdate+','+devtime+',A,'+lat+',N,'+lon+',E,0,'+satcount+',00,'+hdop+','+speed+',0,,,432,11,'+lac+','
            try:
                    clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    result = clientsocket.connect(('ip',port))
                    clientsocket.send(str)
                    data = clientsocket.recv(1024)
                    print(str(datetime.datetime.now())+' -> send completed :'+format(sig[0]))
                    clientsocket.close()
            except:
                    print(str(datetime.datetime.now())+' -> connection to tcp server failed!!')

这会很好用,但有两个无聊的问题:

1) 如果我删除 0.20.6 睡眠延迟脚本崩溃由于重复的套接字使用,似乎系统试图打开另一个套接字,直到前一个还没有完成它的工作!

2) 如果sendData 函数出现问题,整个脚本将停止工作,直到我手动重新启动脚本

如此

1)我可以创建一个线程队列来一个接一个地运行并且不相互影响吗?!

2) 我如何处理线程函数中的错误以仅关闭该特定线程和脚本继续处理下一个数据库记录?!

【问题讨论】:

  • 由于重复使用套接字导致脚本崩溃这是否意味着存在堆栈跟踪?你能发布那个堆栈跟踪吗?
  • 你的循环很奇怪。您查询所有内容,发送第一件事,再次查询所有内容,再次发送第一件事。
  • 我看不出你是如何得到重复的套接字的,除非你在线程中关闭之前没有关闭套接字。 clientsocket.shutdown(socket.SHUT_RDWR).
  • @tdelaney 不,我删掉了代码以避免误解。首先我用工人 id 更新一个 roq,工人选择它的行并尝试用 sendData 线程发送它。这帮助我朗姆酒无限工人发送数据。
  • @tdelaney 我在线程末尾使用了clientsocket.close() 你的意思是我也必须添加clientsocket.shutdown(socket.SHUT_RDWR) !?

标签: python multithreading sockets


【解决方案1】:

这看起来像是线程池的一个很好的应用。在您的实现中,您为数据库表中的每个项目创建一个线程和套接字,这可能会对系统造成极大的负担。在这里,我创建了 20 个工人作为示例。当您开始对系统施加压力时,工人数量的回报就会递减。

import multiprocessing.pool

def sender():
    pool = multiprocessing.pool.ThreadPool(20) # pick your size...
    cursor.execute("select * from database")
    pool.map(sendData, cursor, chunksize=1)

def sendData(sig):
        try:
                clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                result = clientsocket.connect(('ip',port))
                clientsocket.sendall(sig)
                data = clientsocket.recv(1024)
                print(str(datetime.datetime.now())+' -> send completed :'+format(sig[0]))
                clientsocket.shutdown(socket.SOCK_RDWR)
                clientsocket.close()
        except:
                print(str(datetime.datetime.now())+' -> connection to tcp server fa

【讨论】:

  • 嗯,端口忙?这可能是服务器如何配置的问题。它执行listen 并计算允许的最大挂起连接数。拥有比服务器接受的更大的池并没有多大好处。您可以捕获该错误,休眠几秒钟,然后重试。这将有助于自然地跟上服务器可以做的事情。
  • 我的错误。我删除了评论,因为当我们侦听套接字时发生端口繁忙错误,其他程序也尝试侦听该端口。我将测试您提供的代码并在此处更新..谢谢寻求帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多