I have a server-side program in python that is expecting an image and is working fine when tested with a client-side program in python.

I want to send image to this server using flutter and I'm failing to do so..

Here's my server-side code

import socket       #server

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # AF_INET = IP, SOCK_STREAM = TCP
server.bind(('localhost', 1112))  # 127.0.0.1
server.listen()

client_socket, client_address = server.accept()

file = open('2.jpg', "wb")
image_chunk = client_socket.recv(1024)  # stream-based protocol

while image_chunk:
    file.write(image_chunk)
    image_chunk = client_socket.recv(1024)

file.close()
client_socket.close()

I have tried using dio, http and MultiPart

Here are snippets from my failed attempts:

  1. MultiPart

     var uri = Uri.parse('https://10.0.2.2:1112');
     var request = MultipartRequest('POST', uri)
       ..files.add(await MultipartFile.fromPath(
           'picture', filePath,
           contentType: MediaType('application', 'jpeg')));
     var response = await request.send();
     if (response.statusCode == 200) print('Uploaded!');
    
  2. Dio

    Dio dio = new Dio();
     FormData formData = new FormData.fromMap({
       "file": await MultipartFile.fromPath(filePath, filename: basename(filePath),
         contentType: MediaType('application', 'jpeg'),)
     });
    await dio.post('https://10.0.2.2:1112', data: formData);
    

I'm able to create a connection but I'm not able to send the file.

P.S: I have almost no experience of working with sockets, so I'm stuck at this.


Solution 1: Tayo.dev

Since you are dealing with websocket, you have to checkout this package web_socket_channel.

You first need to make connection with your socket channel using

var channel = IOWebSocketChannel.connect(Uri.parse('ws://localhost:1234'));

To listen to changes from your websocket channel, you will use:

 channel.stream.listen((message) {
    print("NEW MESSAGE");
  });

To send data to your websocket channel, you will use:

channel.sink.add("your data");

Finally, do not forget to close your websocket channel stream using:

channel.sink.close();


Solution 2: Moghaddam

The problem is that you are trying to connect to a socket api (not websocket these are different) via HTTP request and on server-side expecting to get image bytes but that's not gonna happen because as you know HTTP has it's own specification RFC2616. so what you will get there is some http headers and body.

Actually you can send http request to a socket but on the server-side you must do the heavy lifting. i mean reading http header line by line and then reading the Transfer-Encoding and Content-Length headers to know how to read the remaining bytes of the request, and then parsing the body data.

The Content-Length entity header indicates the size of the entity-body, in bytes, sent to the recipient.

The Transfer-Encoding header specifies the form of encoding used to safely transfer the payload body to the user.

The solution is either:

  1. using dart socket library at the client side and then sending your image through socket instead of http request (this link might be helpful )

  2. Or creating a RESTFUL API and send your image via http request like you did before.

hope i could help you:)