套接字连接后的Python代码只执行一次

时间:2016-07-15 11:59:42

标签: sockets python-3.x pyserial

该计划的目的是什么:

我想使用套接字将一些命令从客户端发送到服务器,然后服务器使用serial将这些命令发送到Arduino。我希望服务器将来做的另一件事是定期向Arduino发送其他命令而不从客户端获取任何输入,因此套接字需要是非阻塞的,或者需要另一种方式来运行代码与套接字代码分开。

问题是应该将命令发送到Arduino的部分只运行一次。

在Pycharm中使用调试器后我想到的是,问题是在建立连接后以下行阻塞,因此不允许运行其余代码。

conn, addr = s.accept() 

这是正确的,还是有其他错误?

我试图将套接字设置为非阻塞但是当我这样做时,我收到错误。

"BlockingIOError: [WinError 10035] A non-blocking socket operation could not be completed immediately"

我有一些C / C ++和C#的基础知识,并且是Python的新手。

server.py

import socket
import serial
import sys
from _thread import *
import threading
import queue

# command that the client sends are "ON" and "OFF"

class serialConnect:
    comPort =' '
    baudrate = 115200
    myserial = serial.Serial('COM5', baudrate)
    def serialstart(self):
       # self.comPort = input('Comport: ')
        try:
            self.myserial.open()
        except IOError:
            print('Port is already open!')

    def serialRead(self):
        data = self.myserial.read(16)
        data.decode('UTF-8')
        return data

    def serialWrite(self, data):
        data += '\n'        #the arduino needs a \n after each command.
        databytes = data.encode('UTF-8')
        self.myserial.write(databytes)
        print('send data: ', databytes)


def threaded_client(conn, dataqueue):
    data = {bytes}
    conn.send(str.encode('welcome, type your info \n'))
    while True:
        data = conn.recv(2048)
        if not data:
            break
        reply = 'server output: ' + data.decode('UTF-8')
        dataqueue.put(data.decode('UTF-8'))
        print("Items in queue: ",dataqueue.qsize())
        #conn.sendall(str.encode(reply))
        print("Recieved data in threaded_client: ", data.decode('UTF-8') + '\n')

    conn.close()

def Main():

    ser = serialConnect()
    host = ''
    port = 5555
    dataRecieved = 'hello'
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(2)
    s.setblocking(1)   #when set to non-blocking error occurs : "BlockingIOError: [WinError 10035] A non-blocking socket operation could not be completed immediately"
    workQueue = queue.Queue(10)

    try:
        s.bind((host,port))
    except socket.error as e:
        print(str(e))

    s.listen(5)
    print('waiting for a connection')

    while True:
        try:
            conn, addr = s.accept() #once connection is established it blocks?
            print('connected to: ' + addr[0] + ':' + str())
            t = threading.Thread(target=threaded_client, args=(conn, workQueue))
            t.daemon = True
            t.start()

        except:
            e = sys.exc_info()
            print('Error:', e)

        # This section of code is only run once, doesn't matter if put inside try block or not. :(
        dataRecieved = workQueue.get()
        print('The recieved data: ', dataRecieved)
        ser.serialstart()
        ser.serialWrite(dataRecieved)


if __name__ == '__main__':
    Main()

client.py

import socket



def Main():
    host = '127.0.0.1'
    port = 5555

    message = "<,R,G,B,>"
    mySocket = socket.socket()
    mySocket.connect((host, port))

    while message != 'q':
        message = input(" -> ")
        mySocket.send(message.encode())
    mySocket.close()




if __name__ == '__main__':
    Main()

Arduino代码

String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete

int LEDpin = 10;
// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin 13 as an output.
  pinMode(10, OUTPUT);
  Serial.begin(19200);
}

// the loop function runs over and over again forever
void loop() {
  serialEvent();
  if(stringComplete){
    Serial.println(inputString);
    if(inputString == "ON\n"){
      digitalWrite(LEDpin, HIGH);   // turn the LED on (HIGH is the voltage level)
      }
     if(inputString == "OFF\n"){
       digitalWrite(LEDpin, LOW);    // turn the LED off by making the voltage LOW
      }
    inputString = "";
    stringComplete = false;
    }
}
void serialEvent()
{
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

1 个答案:

答案 0 :(得分:2)

对任何对此感兴趣的人重构服务器代码。

我不确定这是否符合标准,但它确实有效。

template