繁体   English   中英

Arduino上的TCP问题。 从Python TCP套接字服务器读取字符串

[英]Issues with TCP on Arduino. Reading Strings from a Python TCP Socket Server

我正在试验新的arduino UNO Rev 3和一个简单的python套接字服务器。 服务器代码为:

##server.py
from socket import *      #import the socket library

#MY FUNCTIONS
def send(data = str):
    conn.send(data.encode())
def recieve():
    recieve.data = conn.recv(BUFSIZE)
    recieve.data = recieve.data.decode()
    return recieve.data

##let's set up some constants
HOST = ''    #we are the host
PORT = 29876    #arbitrary port not currently in use
ADDR = (HOST,PORT)    #we need a tuple for the address
BUFSIZE = 4096    #reasonably sized buffer for data

## now we create a new socket object (serv)
## see the python docs for more information on the socket types/flags
serv = socket( AF_INET,SOCK_STREAM)

##bind our socket to the address
serv.bind((ADDR))    #the double parens are to create a tuple with one element
serv.listen(5)    #5 is the maximum number of queued connections we'll allow
print(" ")
print("Listening")
print(" ")
conn,addr = serv.accept() #accept the connection
print("Connection Established")
send('HELLOCLIENT')
send('%')
leave()

我要做的就是确认我可以与Arduino通信并从那里构建。 这是相关的Arduino代码:

void loop()
{
    int n =-1;
    while (client.connected())
    {
        n++;
        char recieved = client.read();
        inData[n] = recieved; 

        // Process message when new line character is recieved
        if (recieved == '%')
        {
            Serial.print("Arduino Received: ");
            Serial.print(inData);
            n = -1;
        }
    }
    Serial.println();
    Serial.println("Disconnecting.");
    client.stop();

}

我不断得到以下输出:

连接的
收到的Arduino:ÿÿÿÿÿÿÿÿÿÿHELLOCLIENT%
断开。

为什么我收到所有这些填充字符? 我研究了不同的编码方法,并尝试使用ASCII和UTF-32,但是它一直在执行,我缺少什么?

我愿意打赌这是您的问题:

无论您的client对象是什么,它都可能是Arduino 以太网客户端 ,或者是具有相同接口的许多其他类型之一。

如果您在文档中查看read方法,它将返回:

下一个字节(或字符);如果没有可用字节,则为-1。

因此,当您第一次连接时,您立即开始阅读,但尚未发送任何内容,因此前几条阅读全部返回-1。

由于这是一个char ,因此-1和255是相同的值。 在Latin-1(和源自Latin-1的字符集中)中的字符255是ÿ ,因此这就是为什么一开始会看到一堆ÿ的原因。 更改编码会给您带来编码错误,或者将255解释为某些不同的字符,它将无法解决。

那么,您如何解决呢?


可以将某些客户端类(尽管不是全部,而基本的以太网客户端也不是其中之一)进入阻止模式,这意味着read将一直等到要读取的内容为止。


客户端协议实际上并未指定read返回的类型。 某些客户端类型返回int int ,与char不同,您可以区分-1255 但是,一旦将其转换为char ,就会丢弃其他3个字节,并且不再可以这样做。 因此,根据您使用的类型,您可以执行以下操作:

int recieved = client.read();
if (recieved == -1) continue;
inData[n] = (char)recieved;

如果只想发送ASCII文本(因此只有127个值有效),您知道-1永远不会是实际字符。 在这种情况下,您可以执行以下操作:

char recieved = client.read();
if (recieved == -1) continue;

大多数客户端类型都有一个available方法,该方法告诉您有多少字节可读取。 如果返回0 ,请稍等,然后重试,而不是读取:

if (!client.available()) {
    delay(200);
    continue;
}

许多Arduino样本在程序开始时将其与delay(500)或更长的时间放在一起,因为当赔率很高而没有任何东西的时候,浪费时间检查数据是没有意义的。


您可以在协议中添加“开始”字符,就像“结束”字符一样。 继续阅读直到获得%然后断开连接的方式相同,您可以先继续阅读直到获得$字符,然后丢弃直到该点的所有内容:

while (client.connected()) {
    char received = client.read();
    if (received == '$') break;
}
while (client.connected()) {
    /* your original code here */
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM