Localhost simple-chat-app example on windows

My OS : Windows
Docker Image : Alpine Linux

I have two simple-chat-apps, First one is by python, Second one is by rust.
Two apps communicate with udp

Python app details
client = ChatClient(server_host=“127.0.0.1”, server_port=50011)

self.server_host = server_host
self.server_port = server_port
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.client_socket.bind((“127.0.0.1”, 50001))

50001 for recv
50011 for send

Rust app details

let host = “127.0.0.1”;
let receive_port = 50011;
let send_port = 50001;
let socket = UdpSocket::bind(format!(“{}:{}”, host, receive_port))?;

50001 for send
50011 for recv

Two apps works well in my local machine
And I tried to put the server(Rust app) on Docker Container
And I run the app

docker run --net host -p 50001:50001 -p 50011:50011 -it --name my-chat-app-con my-chat-app-img

but this doesn’t work…

here is the inspect of container
I don’t know what is the problem…
I thought ‘–net host’ will work… but It doesn’t work…

please give me some tips.

Each container is its own host, meaning, if you call localhost from within the python container - you will reach the python container

Use the service name instead:

chat = ChatClient(server_host="rust", server_port=50011)

Reaching http://rust:50011

1 Like

Using the host network AND publishing ports at the same time makes no sense, as it already binds the host port (which in this case happens inside the Docker Desktop utility vm) .

Try enabling the “host network driver” in Docker Desktop, set the host to listen on 0.0.0.0, and use the --network host argument without publishing any ports.

1 Like

Client runs on Host Machine(Windows)
Python Code

import socket
import threading

class ChatClient:
    def __init__(self, server_host, server_port):
        self.server_host = server_host
        self.server_port = server_port
        self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

        self.client_socket.bind(("0.0.0.0", 50001))

    def start(self):
        threading.Thread(target=self.receive_messages).start()
        self.send_messages()

    def receive_messages(self):
        while True:
            message, _ = self.client_socket.recvfrom(1024)
            decoded_message = message.decode()

            if decoded_message.lower() == "exit":
                print("Chatting Off.")
                break

            print(f"\n{decoded_message}")

    def send_messages(self):
        while True:
            message = input()
            self.client_socket.sendto(message.encode(), (self.server_host, self.server_port))
            if message.lower() == "exit":
                print("Chatting Off.")
                break

if __name__ == "__main__":
    # client = ChatClient(server_host="172.17.0.2", server_port=50011)
    client = ChatClient(server_host="127.0.0.1", server_port=50011)  
    client.start()
    exit(0)

Server runs on Docker Container

use std::net::UdpSocket;
use std::sync::{Arc, Mutex};
use std::thread;
use std::io::{self, Write};

fn main() -> std::io::Result<()> {
    let host: &str = "0.0.0.0";
    let client_ip: &str = "127.0.0.1";
    let receive_port = 50011; 
    let send_port = 50001;   
    let socket: UdpSocket = UdpSocket::bind(format!("{}:{}", host, receive_port))?;
    println!("Server {}:{}.", host, receive_port);

    let socket = Arc::new(socket);
    let client_address = Arc::new(Mutex::new(Some(format!("{}:{}", client_ip, send_port))));

    // Recv Loop
    let receive_socket = Arc::clone(&socket);
    thread::spawn(move || {
        let mut buf = [0; 1024];
        loop {
            match receive_socket.recv_from(&mut buf) {
                Ok((size, addr)) => {
                    let msg = String::from_utf8_lossy(&buf[..size]);
                    if msg.trim().eq_ignore_ascii_case("exit") {
                        println!("Client Off Chatting.");
                        break;
                    }

                    println!("\r<Client>{}\n<Server>", msg.trim());
                }
                Err(e) => {
                    eprintln!("Msg Recv error: {}", e);
                    break;
                }
            }
        }
    });

    // Send Loop
    let send_socket = Arc::clone(&socket);
    loop {
        let mut input = String::new();
        print!("<Server>");
        io::stdout().flush().unwrap();
        io::stdin().read_line(&mut input)?;

        let message = input.trim();
        if message.eq_ignore_ascii_case("exit") {
            println!("Chatting Off.");
            if let Some(client) = &*client_address.lock().unwrap() {
                let _ = send_socket.send_to(message.as_bytes(), client);
            }
            break;
        }

        if let Some(client) = &*client_address.lock().unwrap() {
            if let Err(e) = send_socket.send_to(message.as_bytes(), client) {
                eprintln!("Msg Send Error: {}", e);
            }
        }
    }

    Ok(())
}

I tried this Docker run command

docker run --network host -it --name my-chat-app-con my-chat-app-img

But It doesn’t work… Sorry

Actually I’m not using the http…
just udp protocol… See the below code…
Thanks a lot!!!

Did you enable this feature in Docker Desktop?

It’s the only way --network host actually makes the ports accessible from the Windows host.

When the feature is disabled and --network host is used, it will bind to private interfaces of the utility vm and can not be accessed from the Windows host.

2 Likes

Thank you some of my errors is fixed!!
Thank you!!

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.