Home  >  Article  >  Backend Development  >  Flutter app can send to UDP server in docker container but cannot receive data sent from server

Flutter app can send to UDP server in docker container but cannot receive data sent from server

WBOY
WBOYforward
2024-02-09 20:00:09626browse

Flutter app can send to UDP server in docker container but cannot receive data sent from server

Flutter app can send to UDP server in docker container but cannot receive data sent from server. This means that in a Flutter application, you can use the UDP protocol to send data to a server running in a docker container. However, when the server tries to send data to the application, the Flutter application cannot receive the data. This may cause limitations in some specific application scenarios, so you need to pay attention to this when developing Flutter applications.

Question content

I am currently developing a backend udp service in go that communicates with a flutter mobile app.

This is the udp service code:

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
        }
    }
}

So far, the service runs using docker and can receive data sent from the flutter application, but the application cannot receive data sent back by the server.

The following are flutter code snippets for receiving and sending messages:

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();
  }
});

The dockerfile of udp service is:

# 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" ]

To run it, I use the following command:

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

I use /udp to map the udp port in the container to port 8080 on the docker host (https://docs.docker.com/config/containers/container-networking/)

However, this only allows me to send data to the service. I know this because checking the docker logs shows that the service is actually receiving data. If I were to run the service using plain old go run instead of using docker, the application could send and receive messages. How can I solve this problem?

Edit: I tried adding expose 8080\udp to the dockerfile instead of just expose 8080 but it still has the same error.

Solution

It turns out that the problem here lies in the flutter code itself. The code snippet below is a valid code snippet.

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(),
);

When using udp code, we have to close the socket on ondone instead of closing the socket while listening, because dart may not have fully received the packet.

The above is the detailed content of Flutter app can send to UDP server in docker container but cannot receive data sent from server. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete