Search code examples
pythonpython-socketsbasehttpserver

HTTPServer: can't listen on Wifi when wire is connected (Windows)


I've encountered an unusual behavior with Python's HTTPServer. My computer has both Ethernet and WiFi connections active simultaneously. I intended for the server to exclusively respond to incoming requests from the WiFi interface, so I configured it accordingly as described below. However, I've encountered an issue where requests are not being served when the Ethernet cable is connected. Strangely enough, when I disconnect the cable, requests are handled successfully.

I suspect that this issue may be related to interface priorities, but I'm not entirely sure. Is there a way to work around this problem? It's worth noting that the Ethernet connection is used for remote control, while the WiFi is dedicated to managing devices within a separate network.

Here is the result for ipconfig:

Ethernet adapter Ethernet:

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::5edd:...
   IPv4 Address. . . . . . . . . . . : 192.168.0.29
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.0.1

Wireless LAN adapter Wi-Fi:

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::904:...
   IPv4 Address. . . . . . . . . . . : 192.168.32.100
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.32.1

I want my server to listen on the WiFi, so I do this:

import socket
from http.server import BaseHTTPRequestHandler, HTTPServer

addr = ('192.168.32.100', 3101)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(addr)
sock.listen()

Then I run several threads with this code:

httpd = HTTPServer(addr, BaseHTTPRequestHandler, False)
# Prevent the HTTP server from re-binding every handler.
# https://stackoverflow.com/questions/46210672/
httpd.socket = sock
httpd.server_bind = self.server_close = lambda self: None
httpd.serve_forever()

EDIT: following @Emmanuel-BERNAT response, I'm adding here the result for route print:

Interface List
  3...c0 25 a5 c8 cf ea ......Intel(R) Ethernet Connection (17) I219-LM
 12...70 a8 d3 d5 d5 ff ......Microsoft Wi-Fi Direct Virtual Adapter
  4...72 a8 d3 d5 d5 fe ......Microsoft Wi-Fi Direct Virtual Adapter #2
 18...70 a8 d3 d5 d5 fe ......Intel(R) Wi-Fi 6E AX211 160MHz
 10...70 a8 d3 d5 d6 02 ......Bluetooth Device (Personal Area Network)
  1...........................Software Loopback Interface 1
===========================================================================

IPv4 Route Table
===========================================================================
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0      192.168.0.1     192.168.0.29     25
          0.0.0.0          0.0.0.0     192.168.32.1   192.168.32.100     40
        127.0.0.0        255.0.0.0         On-link         127.0.0.1    331
        127.0.0.1  255.255.255.255         On-link         127.0.0.1    331
  127.255.255.255  255.255.255.255         On-link         127.0.0.1    331
      192.168.0.0    255.255.255.0         On-link      192.168.0.29    281
     192.168.0.29  255.255.255.255         On-link      192.168.0.29    281
    192.168.0.255  255.255.255.255         On-link      192.168.0.29    281
     192.168.32.0    255.255.255.0         On-link    192.168.32.100    296
   192.168.32.100  255.255.255.255         On-link    192.168.32.100    296
   192.168.32.255  255.255.255.255         On-link    192.168.32.100    296
        224.0.0.0        240.0.0.0         On-link         127.0.0.1    331
        224.0.0.0        240.0.0.0         On-link      192.168.0.29    281
        224.0.0.0        240.0.0.0         On-link    192.168.32.100    296
  255.255.255.255  255.255.255.255         On-link         127.0.0.1    331
  255.255.255.255  255.255.255.255         On-link      192.168.0.29    281
  255.255.255.255  255.255.255.255         On-link    192.168.32.100    296
===========================================================================
Persistent Routes:
  None

IPv6 Route Table
===========================================================================
Active Routes:
 If Metric Network Destination      Gateway
  1    331 ::1/128                  On-link
  3    281 fe80::/64                On-link
 18    296 fe80::/64                On-link
 18    296 fe80::904:e4c2:.../128   On-link
  3    281 fe80::5edd:a253:.../128  On-link
  1    331 ff00::/8                 On-link
  3    281 ff00::/8                 On-link
 18    296 ff00::/8                 On-link
===========================================================================
Persistent Routes:
  None

Solution

  • Seems to me that it's a network config problem. You have two interfaces but both have default gateways. When a packet reach your server, it won't necessarily answer using the same network. I guess your ethernet card has a "Metric" (=priority) inferior to the Wi-Fi card. You can check this with the command route print. If this is the case and if the ethernet network is unable to reach the source, your answer packet will be lost.

    Does the other devices use the same subnet (192.168.32.0/24) on the Wi-Fi side ?