简体   繁体   English

为什么我无法从 tcp 服务器得到响应?

[英]Why I cannot get response from the tcp server?

I have (ESP32 based) device that among other things implements TCP server.我有(基于 ESP32 的)设备,其中包括实现 TCP 服务器。 I can send to it messages in JSON format to change some controls in it.我可以向它发送 JSON 格式的消息以更改其中的一些控件。

I want to be able to control this device from my Android phone.我希望能够通过我的 Android 手机控制此设备。 I wrote an app for it, but I have a problem - my Android app doe not get any response from ESP32 device.我为它写了一个应用程序,但我有一个问题——我的 Android 应用程序没有得到 ESP32 设备的任何响应。 I wrote for tests simple scripts in Python.我在 Python 中为测试编写了简单的脚本。 First one is a client, that sends messages to ESP32.第一个是客户端,它向 ESP32 发送消息。 Second one implements tcp server, so that I can connect my Android app to it and check if response arrives.第二个实现 tcp 服务器,这样我就可以将我的 Android 应用程序连接到它并检查响应是否到达。 Both tests works fine.两项测试都可以正常工作。

Is there anything wrong in my Android code?我的 Android 代码有什么问题吗? I cannot be sure if it is not ESP32 device fault, but please first check my Android code - it is harder to make MCVE from C code for ESP32.我不能确定这是否不是 ESP32 设备故障,但请先检查我的 Android 代码 - 从 ESP32 的 C 代码制作 MCVE 更难。

Here is my Android app's MCVE:这是我的 Android 应用程序的 MCVE:

MainActivity.java: MainActivity.java:

package com.example.tcpclienttest;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

public class MainActivity extends AppCompatActivity {

    String TAG = "******** INFO ********";

    Socket tcpSocket;
    InetAddress IP;
    int tcpPort = 12345;
    PrintWriter mBufferOut;
    BufferedReader mBufferIn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = this.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                new Thread(new Runnable() {
                    public void run() {
                        // try twice in case of tcp error
                        if (SendSetStateCommandTaskFunction()) {
                            Log.i(TAG, "Retrying SendSetStateCommandTask function");
                            SendSetStateCommandTaskFunction();
                        }
                    }
                }).start();

            }
        });
    }

    boolean SendSetStateCommandTaskFunction() {

        boolean retry = false;



        String request_data = "'{\"cmd\":\"set_controls\", \"data\":{\"controls\":{\"name1\":5}}}'";

        try {
            IP = InetAddress.getByName("192.168.1.66");
            if (tcpSocket == null) {
                Log.i(TAG, "Creating new tcp socket");
                tcpSocket = new Socket(IP, tcpPort);
                tcpSocket.setSoTimeout(3000);
                //sends the message to the server
                mBufferOut =
                        new PrintWriter(
                                new BufferedWriter(
                                        new OutputStreamWriter(tcpSocket.getOutputStream())), true);

                //receives the message which the server sends back
                mBufferIn =
                        new BufferedReader(
                                new InputStreamReader(tcpSocket.getInputStream()));
            } else
                Log.i(TAG, "Tcp socket already created");
            if (!tcpSocket.isConnected()) {
                Log.i(TAG, "Connecting to ip addr");
                SocketAddress sockaddr = new InetSocketAddress(IP, tcpPort);
                tcpSocket.connect(sockaddr);
            } else
                Log.i(TAG, "Already connected");

            String in_message;

            mBufferOut.println(request_data);
            mBufferOut.flush();

            in_message = mBufferIn.readLine();

            if (in_message == null) {
                Log.i(TAG, "Received empty message");
                return false;
            }

            Log.i(TAG, in_message);
        } catch (IOException e) {
            Log.e(TAG, "ERROR: " + e.getMessage());
            e.printStackTrace();
            tcpSocket = null;
            retry = true;
        }

        Log.i(TAG, "Finishing SendSetStateCommandTask function");
        return retry;
    }
}

AndroidManifest.xml: AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.tcpclienttest">

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

main_activity.xml: main_activity.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Python client: Python 客户端:

import socket
import json

TCP_IP = "192.168.1.66"
TCP_PORT = 12345

print("TCP target IP:", TCP_IP)
print("TCP target port:", TCP_PORT)

sock = socket.socket(socket.AF_INET, # Internet
                     socket.SOCK_STREAM) # TCP
sock.connect((TCP_IP, TCP_PORT))

MESSAGE = str.encode('{"cmd":"set_controls", "data":{"controls":{"name1":6}}}')

print("message:", MESSAGE)

sock.send(MESSAGE)

data = sock.recv(1024)  # buffer size is 1024 bytes
json_data = json.loads(data.decode("ascii"))
print("received message:")
print(json.dumps(json_data, indent=4))

Python server: Python 服务器:

#!/usr/bin/env python

import socket

TCP_IP = ''
TCP_PORT = 12345
BUFFER_SIZE = 1024

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)

conn, addr = s.accept()
print('Connection address:', addr)
while 1:
    data = conn.recv(BUFFER_SIZE)
    if not data:
        break
    print("received data:", data)
    conn.send(data)  # echo
conn.close()

Console log from the app lanuch, after clicking SEND button:点击SEND按钮后,来自 app lanuch 的控制台日志:

I/ViewRootImpl: jank_removeInvalidNode all the node in jank list is out of time
V/AudioManager: playSoundEffect   effectType: 0
    querySoundEffectsEnabled...
I/******** INFO ********: Creating new tcp socket
I/******** INFO ********: Already connected
E/******** INFO ********: ERROR: Read timed out
W/System.err: java.net.SocketTimeoutException: Read timed out
W/System.err:     at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.socketRead(SocketInputStream.java:119)
W/System.err:     at java.net.SocketInputStream.read(SocketInputStream.java:176)
        at java.net.SocketInputStream.read(SocketInputStream.java:144)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:288)
W/System.err:     at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:351)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:180)
W/System.err:     at java.io.InputStreamReader.read(InputStreamReader.java:184)
        at java.io.BufferedReader.fill(BufferedReader.java:172)
W/System.err:     at java.io.BufferedReader.readLine(BufferedReader.java:335)
        at java.io.BufferedReader.readLine(BufferedReader.java:400)
        at com.example.tcpclienttest.MainActivity.SendSetStateCommandTaskFunction(MainActivity.java:93)
W/System.err:     at com.example.tcpclienttest.MainActivity$1$1.run(MainActivity.java:44)
        at java.lang.Thread.run(Thread.java:784)
I/******** INFO ********: Finishing SendSetStateCommandTask function
I/******** INFO ********: Retrying SendSetStateCommandTask function
    Creating new tcp socket
I/******** INFO ********: Already connected
E/******** INFO ********: ERROR: Read timed out
W/System.err: java.net.SocketTimeoutException: Read timed out
W/System.err:     at java.net.SocketInputStream.socketRead0(Native Method)
W/System.err:     at java.net.SocketInputStream.socketRead(SocketInputStream.java:119)
        at java.net.SocketInputStream.read(SocketInputStream.java:176)
W/System.err:     at java.net.SocketInputStream.read(SocketInputStream.java:144)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:288)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:351)
W/System.err:     at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:180)
        at java.io.InputStreamReader.read(InputStreamReader.java:184)
W/System.err:     at java.io.BufferedReader.fill(BufferedReader.java:172)
        at java.io.BufferedReader.readLine(BufferedReader.java:335)
W/System.err:     at java.io.BufferedReader.readLine(BufferedReader.java:400)
        at com.example.tcpclienttest.MainActivity.SendSetStateCommandTaskFunction(MainActivity.java:93)
        at com.example.tcpclienttest.MainActivity$1$1.run(MainActivity.java:46)
W/System.err:     at java.lang.Thread.run(Thread.java:784)
I/******** INFO ********: Finishing SendSetStateCommandTask function

The problem was probably related to lack of new line character at the end of the response.该问题可能与响应末尾缺少换行符有关。 Adding it didn't help instantly, but after some more changes in the server, Android app started to be able to get the response.添加它并没有立即帮助,但在服务器中进行了更多更改后,Android 应用程序开始能够获得响应。 I cannot tell what exactly was the problem after adding the new line character.添加换行符后,我无法确定问题到底出在哪里。

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

相关问题 为什么我没有从TCP服务器和客户端收到任何消息? - Why do I not get any messages from my TCP Server and Client? 无法从PHP套接字服务器获取响应 - Cannot get response from PHP socket server 为什么我无法发送正确的服务器状态作为响应,而是在我点击端点时得到“无响应”? - Why I cannot send proper Server status as response and instead I get a "no response" when I hit my endpoint? 我如何从Java中的服务器TCP获得答复 - How can i get the reply from server TCP in java 我必须从服务器获取响应代码吗? - Must I Get The Response Code From The Server? TCP:如何从Android客户端中的Vb.net服务器获取响应? - TCP: How to get response from Vb.net server in Android Client? 我试图从服务器获取响应并使用JSON检索它。 java.lang.string无法转换为jsonObject - i m trying to get response from server and retrieving it using JSON. java.lang.string cannot be convert into jsonObject 为什么我无法从android获取值? - Why I cannot get a value from android? 尝试从服务器获取响应时出现EOFException - I get EOFException while trying to get response from the server 为什么在此代码中我没有从服务器得到任何响应 - Why I'm not getting any response from server in this code
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM