关于从 android 设备接收文件到 esp8266 的问题

Problem regarding receiving files from android device into the esp8266

我一直在做一个项目,我会从我写的 android 应用程序发送一个文件到我的 esp8266;然后 esp8266 会将文件写入 SD 卡。但是当 esp 收到文件时,例如 .jpg,它都是乱码和嘈杂的。 如果我收到一个 .txt 文件,它总是会在开头添加一个 (¬í ur [B¬óøTà xp ¬),无论我使用什么方法。

这是我的 android 代码: (服务器线程)

Socket mySocket = null;
ServerSocket serverSocket = null;

class ServerThread implements Runnable{
    int serverPort;
    public ServerThread(int serverPort){
        this.serverPort = serverPort;
    }
    @Override
    public void run() {
        try {
            serverSocket = new ServerSocket(serverPort);
            mySocket = serverSocket.accept();
            output = new PrintWriter(mySocket.getOutputStream());
            input = new BufferedReader(new InputStreamReader(mySocket.getInputStream()));
            Log.i("connection", "server");

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    connection_state = true;
                    LinearLayout.LayoutParams textParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                    TextView thisText = new TextView(MainActivity.this);
                    thisText.setId(append);
                    thisText.setText("Server port: " + 8080 + " ... A client just made connection");
                    thisText.setTextSize(20);
                    thisText.setBackgroundColor(Color.rgb(25, 24, 24));
                    thisText.setTextColor(Color.rgb(0, 100, 0));
                    append++;
                    thisText.setGravity(20);
                    thisText.setLayoutParams(textParams);
                    myTexts.addView(thisText);
                }
            });
            new Thread(new ReceiveStringThread()).start();
        } catch (IOException e) {
            e.printStackTrace();
            Log.i("connection", "couldn't establish connection");
        } finally {
            try {
                if (socket != null)
                    socket.close();
                if (serverSocket != null)
                    serverSocket.close();

            }catch (IOException e){
               e.getStackTrace();
            }
        }
    }
}

发送文件线程:

class SendFileThread implements Runnable{
    String filePath;

    SendFileThread(String filePath) {
        this.filePath = filePath;
    }

    @Override
    public void run() {
        if(connection_state) {
            File findFile = new File(filePath);

            byte[] sendIt = new byte[(int) findFile.length()];

            try {
                BufferedInputStream bufferFile = new BufferedInputStream(new FileInputStream(findFile));

                bufferFile.read(sendIt, 0, sendIt.length);
                ObjectOutputStream oos = new ObjectOutputStream(mySocket.getOutputStream());
                oos.writeObject(sendIt);
                oos.flush();

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, "File was sent successfully. size: " +
                                       (int) findFile.length() + " bytes", Toast.LENGTH_SHORT).show();
                    }
                });

            } catch (IOException e) {
                e.getStackTrace();
            }finally {
                try {
                    mySocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

这是我用于 esp8266 的 arduino 代码:

#include <ESP8266WiFi.h>
#include <SD.h>

#ifndef STASSID
#define STASSID "ESP_CLIENT"
#define STAPSK  "client-1234"
#endif

const char* ssid     = STASSID;
const char* password = STAPSK;

const char* host = "192.168.1.103";
const uint16_t port = 8080;

boolean connectionStatus = false;

byte buffer_array[10] = {'0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00'};
int num_read;

WiFiClient client;

void setup() {
    Serial.begin(57600);

    //.................Initiate SD card................//
    if(!SD.begin(SS)){
        Serial.println("SD card initialization failed!");
        return;
    }else{
        Serial.println("SD card initialized successfully");
    }

    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }

    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
}

char *printBytes(byte *bytes) {
  char bytesStr[10];
  sprintf(bytesStr, "%02X", *bytes);
  Serial.print("byte: ");
  Serial.println(bytesStr);  

  return bytesStr;
}

void loop() {
    if(!connectionStatus){
        Serial.print("connecting to ");
        Serial.print(host);
        Serial.print(':');
        Serial.println(port);
        
        if (!client.connect(host, port)) {
            Serial.println("********************************************Connection failed************************************************");
            connectionStatus = false;
            delay(1000);
            return;
        }else{
            Serial.println("********************************************Connection established with server***********************************************");
            connectionStatus = true;
        }
        
        Serial.println("sending data to server");
        if (client.connected()) {
          client.println("hello from ESP8266");
        }
    }
    
    if(client.available()){
        Serial.println("Receiving...");
        num_read = client.readBytesUntil('\n',buffer_array, 10);
        Serial.println("bytes read: " + (String)num_read);
        printBytes(buffer_array);

        File appendSD = SD.open("/testESP32.txt", FILE_WRITE);
        if(!appendSD){
            Serial.println("not found");
            return;
        }else{
            Serial.println("Writing byte to file...");
            appendSD.write(buffer_array, num_read);
            appendSD.close();
        }
    }
}

无论我将它们置于哪种模式,无论是将 esp 作为服务器还是将 android 设备作为客户端或反向,都不会产生任何影响。

有人知道如何解决这个问题吗?

我修改了 SendFileThread 如下,但它只适用于正确发送 .txt 文件。但是发送.jpg之类的图片文件问题依然存在

class SendFileThread implements Runnable{
    String filePath;

    SendFileThread(String filePath) {
        this.filePath = filePath;
    }

    @Override
    public void run() {
        if(connection_state) {
            File findFile = new File(filePath);

            byte[] sendIt = new byte[(int) findFile.length()];

            try {
                BufferedInputStream bufferFile = new BufferedInputStream(new FileInputStream(findFile));

                bufferFile.read(sendIt, 0, sendIt.length);
                OutputStream os= mySocket.getOutputStream();
                os.write(sendIt);
                os.flush();

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, "File was sent successfully. size: " +
                                       (int) findFile.length() + " bytes", Toast.LENGTH_SHORT).show();
                    }
                });

            } catch (IOException e) {
                e.getStackTrace();
            }finally {
                try {
                    mySocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }else{

        }
    }
}

而且我希望能够发送各种数据,如 .pdf .doxs 以及 ObjectOutputStream 发送所有这些类型的文件,如果我将它们发送到另一个 android phone 不是 esp8266

已解决:我用过

client.read(buffer_array, 10);

用于图像文件而不是

client.readBytesUntil('\n', buffer_array, 10);

并在 android 中更改了

ObjectOutputStream oos = new ObjectOutputStream(mySocket.getOutputStream());
        oos.writeObject(sendIt);

OutputStream os= mySocket.getOutputStream();
            os.write(sendIt);

它终于适用于所有类型的文件!