首頁 > 後端開發 > Golang > Flutter應用程式可以傳送到docker容器中的UDP伺服器,但無法接收從伺服器傳送的數據

Flutter應用程式可以傳送到docker容器中的UDP伺服器,但無法接收從伺服器傳送的數據

WBOY
發布: 2024-02-09 20:00:09
轉載
691 人瀏覽過

Flutter應用程式可以傳送到docker容器中的UDP伺服器,但無法接收從伺服器傳送的數據

Flutter應用程式可以傳送到docker容器中的UDP伺服器,但無法接收從伺服器傳送的資料。這意味著在Flutter應用程式中,您可以使用UDP協定將資料傳送到docker容器中執行的伺服器。但是,當伺服器嘗試向應用程式發送資料時,Flutter應用程式無法接收這些資料。這可能會對某些特定的應用程式場景造成限制,因此在開發Flutter應用程式時,需要注意這一點。

問題內容

我目前正在 go 中開發後端 udp 服務,該服務與 flutter 行動應用程式進行通訊。

這是 udp 服務代碼:

package main

import (
    "log"
    "net"
    "os"
    "time"
)

func main() {
    port := ":8080"

    logger := log.new(os.stdout, "", log.ldate|log.ltime)

    udp_server, err := net.resolveudpaddr("udp4", port)

    if err != nil {
        logger.fatalln(err.error())
        return 
    }

    udp_connection, err := net.listenudp("udp4", udp_server)

    if err != nil {
        logger.fatalln(err.error())
        return 
    }

    defer udp_connection.close()

    buffer := make([]byte, 1024)

    for {
        n, addr, err := udp_connection.readfromudp(buffer)
        if err != nil {
            udp_connection.writetoudp([]byte("error reading from udp connection"), addr)
        }
        
        buffer_string := string(buffer[0:n])

        time_sent := time.now()
        time_sent_string := time_sent.string()
    
        combined_string := buffer_string + time_sent_string
        data := []byte(combined_string);
        logger.println(combined_string);

        _, err = udp_connection.writetoudp(data, addr)
        if err != nil {
            logger.fatalln(err.error())
            return
        }
    }
}
登入後複製

到目前為止,該服務使用 docker 運行,可以接收從 flutter 應用程式發送的數據,但應用程式無法接收伺服器發送回的資料。

以下是用於接收和發送訊息的 flutter 程式碼片段:

final socket = await rawdatagramsocket.bind(internetaddress.anyipv4, 0).onerror((error, stacktrace) => throw error assocketexception);
              
final server = internetaddress("10.0.2.2");
final port = 8080;

final data = [
  deviceinfodata.deviceid,
  datetime.now().toutc().tostring()
];

datetime current = datetime.now();
late datetime responsetime;

socket.send(data.tostring().codeunits, server, port);

string serverout = "";

socket.listen((event) {
  final datagram = socket.receive();
  if (datagram != null) {
    // print("data sent to server: ${datagram.data}");
    string message = string.fromcharcodes(datagram.data);
    serverout = message.split("]").last;
    log(message);
    socket.close();
  } else {
    socket.close();
  }
});
登入後複製

udp服務的dockerfile是:

# Specifies a parent image
FROM golang:1.19.2-bullseye
 
# Creates an app directory to hold your app’s source code
WORKDIR /app
 
# Copies everything from your root directory into /app
COPY . .
 
# Installs Go dependencies
RUN go mod download
 
# Builds your app with optional configuration
RUN go build -o /udp-go
 
# Tells Docker which network port your container listens on
EXPOSE 8080
 
# Specifies the executable command that runs when the container starts
CMD [ "/udp-go" ]
登入後複製

為了運行它,我使用以下命令:

  1. docker 建置 --rm -t udp-go:alpha .
  2. docker run -d -p 8080:8080/udp --name go-udp udp-go:alpha

我使用/udp將容器中的udp連接埠對應到docker主機上的8080連接埠(https://docs.docker.com/config/containers/container-networking/)

但是,這僅允許我向服務發送資料。我知道這一點是因為檢查 docker 日誌顯示該服務實際上正在接收資料。如果我要使用普通的舊 go run 而不是使用 docker 運行服務,則應用程式可以發送和接收訊息。我該如何解決這個問題?

編輯:我嘗試將 expose 8080\udp 新增到 dockerfile 而不僅僅是 expose 8080 但它仍然存在相同的錯誤。

解決方法

事實證明,這裡的問題在於 flutter 程式碼本身。下面的程式碼片段是有效的程式碼片段。

final socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0).onError((error, stackTrace) => throw error asSocketException);
              
final server = InternetAddress("10.0.2.2");
final port = 8080;

final data = [
  deviceInfoData.deviceId,
  DateTime.now().toUtc().toString()
];

DateTime current = DateTime.now();
late DateTime responseTime;

socket.send(data.toString().codeUnits, server, port);

String serverOut = "";

socket.listen((event) {
  final datagram = socket.receive();
  if (datagram != null) {
    // print("Data sent to server: ${datagram.data}");
    String message = String.fromCharCodes(datagram.data);
    serverOut = message.split("]").last;
    log(message);
  } 
},
onDone: () => socket.close(),
);
登入後複製

使用 udp 程式碼時,我們必須關閉 ondone 上的套接字,而不是在監聽時關閉套接字,因為 dart 可能尚未完全接收封包。

以上是Flutter應用程式可以傳送到docker容器中的UDP伺服器,但無法接收從伺服器傳送的數據的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板