socket.recv(Python)

时间:2017-02-21 13:45:56

标签: python python-2.7 sockets

我得到了一个小型python程序,通过BT与EV3机器人(乐高的机器人)进行通信。程序向EV3发送1/2或3的数字,机器人进行预定义的运动并发回“A”以指示运动已完成并且已准备好进行下一个命令。

系统工作得很好但偶尔python应用程序会崩溃并显示以下错误消息: “已建立的连接已被主机中的软件中止。”这来自在btListener()线程中调用的socket.recv。

相关的python部分:

    import bluetooth
    from gmail import *
    import re
    from gtts import gTTS
    from time import sleep
    import pygame
    import serial
    import thread
    import os
    import ftplib
    from StringIO import StringIO
    from blynkapi import Blynk

    def a():    #Send 'a' to 'Status' mailbox
        print "Send a to robot"
        for i in commandA:
            client_sock.send(chr(i))
        sleep(1)

    def b():    # Send 'b' to 'Status' mailbox


    def c():     # Send 'c' to 'Status' mailbox


    def clear():  # Send clear array to 'Status' mailbox
        for i in clearArray:
            client_sock.send(chr(i))

    def btListener():
        # Listen for end of run reply from the EV3
        global ev3Flag, listenFlag
        while True:
            if listenFlag and (not ev3Flag):
                    try:
                        data = client_sock.recv(1024)     #Check if EV3 is ready for new command
                        if data[-2] == 'A':
                            ev3Flag = True
                            print "Received 'Ready' from EV3  "
                            sleep(1)
                    except Exception as e:
                        print(e)
                        print "Failed to read data from socket"


    def queueHandler():
        # Read next command from QueueArray, call sendFunc and clear the queue
        global ev3Flag, listenFlag, queueArray
        while True:
            if len(queueArray) > 0 and ev3Flag:
                sendFunc(queueArray[0])
                queueArray.pop(0)


    def sendFunc(cmd):
        #Send the next command on QueueArray to the EV3
        global ev3Flag, listenFlag
        if cmd == 1:
            try:
                ev3Flag = False
                listenFlag = False
                a()
                listenFlag = True
                sleep(3)                
                clear()                 # clear the EV3 btsocket with a default message
            except Exception as e:
                print "Error on sendFunc cmd = 1"
                print(e)

        elif cmd == 2:
            try:
            except Exception as e:

        elif cmd == 3:
            try:
            except Exception as e:


    if __name__ == "__main__":
        # Blynk setup
        blynk = Blynk(auth_token)
        switch1 = Blynk(auth_token, pin = "V0")
        switch2 = Blynk(auth_token, pin = "V1")
        switch3 = Blynk(auth_token, pin = "V2")
        print "Blynk connected"

        queueArray = []  # Queue array to hold incoming commands
        listenFlag = True  # Listen to message from EV3
        ev3Flag = True  # EV3 ready for new command flag

        # BT CONNECTION WITH EV3 #
        print "Searching for BT connections: "

        nearby_devices = bluetooth.discover_devices()

        for bdaddr in nearby_devices:
            print bdaddr + "  -  " + bluetooth.lookup_name(bdaddr)
            if target_name == bluetooth.lookup_name(bdaddr):
                target_address = bdaddr
                break

        server_sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)

        port = 1
        server_sock.bind(("", port))
        server_sock.listen(1)

        client_sock, address = server_sock.accept()
        print "Accepted connection from ", address

        if target_address is not None:
            print "found target bluetooth device with address ", target_address
        else:
            print "could not find target bluetooth device nearby"
        # END BT CONNECTION WITH EV3 #

        try:
            thread.start_new_thread(queueHandler, ())
        except Exception as e: print(e)

        try:
              thread.start_new_thread(btListener, ())
        except Exception as e: print(e)


    while True:
        res1 = switch1.get_val()
        res2 = switch2.get_val()
        res3 = switch3.get_val()

        if (int)(res1[0]) == 1:
            print "Add 1 to queue"
            queueArray.append(1)

        if (int)(res2[0]) == 1:
            print "Add 2 to queue"
            queueArray.append(2)

        if (int)(res3[0]) == 1:
            print "Add 3 to queue"
            queueArray.append(3)

修改1:

我测试了一下,似乎当程序试图同时恢复数据并发送数据时会发生压榨。 (通过clear()或a()/ b()/ c()函数),可能是这种情况吗? 我是套接字的新手,所以第一个想到的解决方案是创建一个标志来限制套接字的操作,是否有更好/更聪明的方法来防止这种情况发生?

编辑2:

在调用clear()之后,我将sendFunc()中的'listenFlag = True'行移动到了它,它似乎解决了可能是因为python程序试图同时接收和打磨的问题。 / p>

1 个答案:

答案 0 :(得分:0)

在调用clear()之后,我将sendFunc()中的'listenFlag = True'行移动到了它,它似乎解决了可能是因为python程序试图同时接收和打磨的问题。 / p>