猿问

Python(服务器)在单独的行中从 Java(客户端)接收数据..(TCP)

好的,所以我读了很多问题,但无法弄清楚。我从我的 Android 应用程序收到的数据遇到问题。基本上我想控制伺服。该代码有效,但应用程序发送到服务器的数据是在单独的行中接收的。是的,我知道我需要使用缓冲区,我进行了一些研究,但找不到向我的代码添加缓冲区的方法。此外,我认为我不需要显示我的 Java 代码,因为它只是从按钮点击发送的基本命令(向上、向下等字符串)。


...Python Code(Server)...

  ctrCmd = ['Up','Down', 'ON', 'OFF']

  ...

  ...

  while True:

        print ("Waiting for connection")

        tcpCliSock,addr = tcpSerSock.accept()

        print ("...connected from :", addr)


    try:

            while True:

                    data = ''

                    data = tcpCliSock.recv(BUFSIZE).decode()

                    print("This",data)


                    if not data:

                            print ("No Data",data)

                            break

                    if data == ctrCmd[0]:

                            print("I am here")

                            Servomotor.ServoUp()

                            print ("Increase: ",Servomotor.cur_X)

                            #tcpCliSock.send("Servo Increases".encode())

                    if data == ctrCmd[1]:

                            Servomotor.ServoDown()

                            print ("Decrease: ",Servomotor.cur_X)

                            #tcpCliSock.send("Servo Decreases".encode())

                    if data == ctrCmd[2]:

                            Servomotor.ledOn()

                            print ("Led On")

                            #tcpCliSock.send("Led On".encode())

                    if data == ctrCmd[3]:

                            Servomotor.ledOff()

                            print ("Led Off")

                           # tcpCliSock.send("Led Off".encode())

    except KeyboardInterrupt:

            Servomotor.close()

            GPIO.cleanup()

tcpSerSock.close();


慕少森
浏览 98回答 3
3回答

精慕HU

试试看:socket = new java.net.Socket(inetAddress,MainActivity.wifiModulePort);//read input msg from serverDataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());dataOutputStream.writeChars(CMD);System.out.println(CMD);dataOutputStream.close();socket.close();如果这增加了额外的空间,那么简单的解决方案是继续使用 writeutf 并在服务器端对数据进行子字符串化socket = new java.net.Socket(inetAddress,MainActivity.wifiModulePort);//read input msg from serverDataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());dataOutputStream.writeUTF(CMD);System.out.println(CMD);dataOutputStream.close();socket.close();在服务器端:data = tcpCliSock.recv(BUFSIZE).decode()data = data[2:]引用自 Javadoc:以与机器无关的方式使用修改后的 UTF-8 编码将字符串写入基础输出流。首先,将两个字节写入输出流,就像使用 writeShort 方法一样,给出后面的字节数。这个值是实际写出的字节数,而不是字符串的长度。在长度之后,字符串的每个字符按顺序输出,使用字符的修改后的 UTF-8 编码。如果没有抛出异常,写入的计数器将增加写入输出流的字节总数。这将至少是 str 长度的两倍,最多是 str 长度的两倍。

陪伴而非守候

请向服务器提供您的 Android 代码片段(您发送消息的位置)。当我在本地机器上运行代码时(我没有树莓派控制器,所以我注释掉了某些行):import sysimport socketimport selectctrCmd = ['Up', 'Down', 'Left', 'Right', 'Stop', 'Connect']HOST = ''PORT = 21567BUFSIZE = 1024ADDR = (HOST, PORT)tcpSerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcpSerSock.bind(ADDR)tcpSerSock.listen(1)print('Waiting for connection')sendInterval = 1.0&nbsp; # interval(sec) for sending messages to connected clientsrxset = [tcpSerSock]txset = []while True:&nbsp; &nbsp; print("Waiting for connection")&nbsp; &nbsp; tcpCliSock, addr = tcpSerSock.accept()&nbsp; &nbsp; print("...connected from :", addr)&nbsp; &nbsp; try:&nbsp; &nbsp; &nbsp; &nbsp; while True:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data = ''&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data = tcpCliSock.recv(BUFSIZE).decode()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("This", data)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if not data:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("No Data", data)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if data == ctrCmd[0]:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("I am here")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Servomotor.ServoUp()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("Increase: ")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; #tcpCliSock.send("Servo Increases".encode())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if data == ctrCmd[1]:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Servomotor.ServoDown()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("Decrease: ")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; #tcpCliSock.send("Servo Decreases".encode())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if data == ctrCmd[2]:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Servomotor.ledOn()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("Led On")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; #tcpCliSock.send("Led On".encode())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if data == ctrCmd[3]:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Servomotor.ledOff()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("Led Off")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# tcpCliSock.send("Led Off".encode())&nbsp; &nbsp; except KeyboardInterrupt:&nbsp; &nbsp; &nbsp; &nbsp; # Servomotor.close()&nbsp; &nbsp; &nbsp; &nbsp; # GPIO.cleanup()&nbsp; &nbsp; &nbsp; &nbsp; print('Exception')tcpSerSock.close()在客户端运行以下代码:import sysimport socketimport timectrCmd = [b'Up', b'Down', b'Left', b'Right', b'Stop', b'Connect']HOST = '127.0.0.1'PORT = 21567BUFSIZE = 1024ADDR = (HOST, PORT)tcpCliSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcpCliSock.connect(ADDR)time.sleep(1)for i in range(len(ctrCmd)):&nbsp; &nbsp; tcpCliSock.send(ctrCmd[i])&nbsp; &nbsp; time.sleep(1)data = tcpCliSock.recv(BUFSIZE)print(data)tcpCliSock.close()我最终收到的是:Waiting for connectionWaiting for connection...connected from : ('127.0.0.1', 54430)This UpI am hereIncrease:This DownDecrease:This LeftLed OnThis RightLed OffThis StopThis Connect您可能已经注意到,关键是在客户端我发送的不是字符串而是字节数组(b'Up',而不是'Up')。因此,如您所见,服务器端没有问题。可能在你的 Android 端你需要这样的东西:String msg = "Up"byte[] byteArr = msg.getBytes();更新好的,我想我知道那里发生了什么。使用套接字的输出流,您只能发送字节数据。它实际上所做的是将您的消息转换为字节数组 (CMD.getBytes())。毫不奇怪,您的服务器正在一步一步、逐字节地接收所有内容。你需要做的是:&nbsp; &nbsp; public class MainActivity extends AppCompatActivity {&nbsp; &nbsp; //UI Element&nbsp; &nbsp; Button btnUp;&nbsp; &nbsp; Button btnDown;&nbsp; &nbsp; Button btnLedOn;&nbsp; &nbsp; Button btnLedOff;&nbsp; &nbsp; EditText txtAddress;&nbsp; &nbsp; /*TextView message;*/&nbsp; &nbsp; Socket myAppSocket = null;&nbsp; &nbsp; public static String wifiModuleIp = "";&nbsp; &nbsp; public static int wifiModulePort = 0;&nbsp; &nbsp; public static String CMD = "0";&nbsp; &nbsp; @Override&nbsp; &nbsp; protected void onCreate(Bundle savedInstanceState) {&nbsp; &nbsp; &nbsp; &nbsp; super.onCreate(savedInstanceState);&nbsp; &nbsp; &nbsp; &nbsp; setContentView(R.layout.activity_main);&nbsp; &nbsp; &nbsp; &nbsp; btnUp = (Button) findViewById(R.id.btnUp);&nbsp; &nbsp; &nbsp; &nbsp; btnDown = (Button) findViewById(R.id.btnDown);&nbsp; &nbsp; &nbsp; &nbsp; btnLedOn = (Button) findViewById(R.id.btnLedOn);&nbsp; &nbsp; &nbsp; &nbsp; btnLedOff = (Button) findViewById(R.id.btnLedOff);&nbsp; &nbsp; &nbsp; &nbsp; txtAddress = (EditText) findViewById(R.id.ipAddress);&nbsp; &nbsp; &nbsp; &nbsp; /*message = (TextView) findViewById(R.id.message);*/&nbsp; &nbsp; &nbsp; &nbsp; btnUp.setOnClickListener(new View.OnClickListener() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void onClick(View v) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; getIPandPort();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CMD = "Up";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Socket_AsyncTask cmd_increase_servo = new Socket_AsyncTask();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cmd_increase_servo.execute();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; btnDown.setOnClickListener(new View.OnClickListener() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void onClick(View v) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; getIPandPort();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CMD = "Down";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Socket_AsyncTask cmd_increase_servo = new Socket_AsyncTask();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cmd_increase_servo.execute();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; btnLedOn.setOnClickListener(new View.OnClickListener() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void onClick(View v) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; getIPandPort();;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CMD = "ON";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Socket_AsyncTask cmd_led_on = new Socket_AsyncTask();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cmd_led_on.execute();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; btnLedOff.setOnClickListener(new View.OnClickListener() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void onClick(View v) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; getIPandPort();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CMD = "OFF";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Socket_AsyncTask cmd_led_off = new Socket_AsyncTask();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cmd_led_off.execute();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; }&nbsp; &nbsp; public void getIPandPort()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; String iPandPort = txtAddress.getText().toString();&nbsp; &nbsp; &nbsp; &nbsp; Log.d("MYTEST","IP String: "+ iPandPort);&nbsp; &nbsp; &nbsp; &nbsp; String temp[]= iPandPort.split(":");&nbsp; &nbsp; &nbsp; &nbsp; wifiModuleIp = temp[0];&nbsp; &nbsp; &nbsp; &nbsp; wifiModulePort = Integer.valueOf(temp[1]);&nbsp; &nbsp; &nbsp; &nbsp; Log.d("MY TEST","IP:" +wifiModuleIp);&nbsp; &nbsp; &nbsp; &nbsp; Log.d("MY TEST","PORT:"+wifiModulePort);&nbsp; &nbsp; }&nbsp; &nbsp; public class Socket_AsyncTask extends AsyncTask<Void,Void,Void>&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Socket socket;&nbsp; &nbsp; &nbsp; &nbsp; OutputStreamWriter osw;&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; protected Void doInBackground(Void... params){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; InetAddress inetAddress = InetAddress.getByName(MainActivity.wifiModuleIp);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; socket = new java.net.Socket(inetAddress,MainActivity.wifiModulePort);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //read input msg from server&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; osw = new OutputStreamWriter(socket.getOutputStream(), 'UTF-8');&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; osw.write(CMD, 0, CMD.length());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.flush();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; socket.close();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }catch (UnknownHostException e){e.printStackTrace();}catch (IOException e){e.printStackTrace();}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}

呼啦一阵风

if not "some string"不会等于 True。您可能想将其更改为:if data != "" :&nbsp; &nbsp; # process here&nbsp; &nbsp; pass您在单独的行中收到数据,可能是因为单独发送。你可以看看我曾经为 TCP 套接字编写的代码。 套接字也ctrCmd[0]等于'Up'和你的数据内容,正如我在 shell 中看到的那样,是像'U'和这样的字符'P'。所以这条线if data == ctrCmd[0]:&nbsp; &nbsp; print("I am here")不会运行,因为'Up'不等于'U'.
随时随地看视频慕课网APP

相关分类

Java
我要回答