Simple_web_server.py can not get remote request

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
allankliu
Posts: 11
Joined: Fri Mar 30, 2018 11:13 am

Simple_web_server.py can not get remote request

Post by allankliu » Mon Apr 02, 2018 2:12 am

I tried two codebase, one from MicroPython's tutorial, called simple_web_server.py, with small modification for sta mode.

Code: Select all

import socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]

def do_connect():
    import network
    sta_if = network.WLAN(network.STA_IF)
    if not sta_if.isconnected():
        print('connecting to WiFi...')
        sta_if.active(True)
        sta_if.connect('CMCC-302', 'mypassword')
        while not sta_if.isconnected():
            pass
    print('ifconfig:', sta_if.ifconfig())
    return sta_if

sta_if = do_connect()

s = socket.socket()
s.bind(addr)
s.listen(1)

print('listening on', addr)

while True:
    cl, addr = s.accept()
    print('cl', cl)
    print('client connected from', addr)
    cl_file = cl.makefile('rwb', 0)
    print('cl_file', cl_file)
    while True:
        line = cl_file.readline()
        print('line:'line)
    response = line
    cl.send(response)
    cl.close()
--------------------------
The MicroPython REPL

Code: Select all

MicroPython v1.9.3-500-gbc3a5f19 on 2018-03-30; ESP module with ESP8266
Type "help()" for more information.
>>> import tcpserver_test
ifconfig: ('192.168.1.14', '255.255.255.0', '192.168.1.1', '192.168.1.1')
listening on ('0.0.0.0', 80)

cl <socket state=2 timeout=-1 incoming=0 off=0>
client connected from ('192.168.1.12', 62125)
cl_file <socket state=2 timeout=-1 incoming=0 off=0>

--------------------------

PC client

Code: Select all

>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> s.connect(('192.168.1.14',80))
>>> s.send(b'Hello')
5
>>> s.setblocking(False)
>>> s.recv(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
BlockingIOError: [WinError 10035]
It seems the line = cl_file.readline() get None .

================================

The other comes from 3rd party from github, let us call it httpserver_demo.py:

Code: Select all

import usocket as socket
import time
import network

CONTENT = b"HTTP/1.0 200 OK\r\nTemperature is {}.{}"

newline = b"\r\n"

def answer_request(client_socket, client_addr):
    req = client_socket.readline()
    print("Request:")
    print(req)
    while True:
        h = client_socket.readline()
        if h == b"" or h == newline or h == None:
            break
        print(h)
    temperature, temperature_decimal = (15,15)
    alive = time.time() - 473385595
    data = CONTENT.format(alive, temperature, temperature_decimal)
    client_socket.setblocking(True)
    client_socket.write(data)
    client_socket.setblocking(False)
    client_socket.close()

def main():
    s = socket.socket()
    ai = socket.getaddrinfo("0.0.0.0", 80)
    print("Bind address info:", ai)

    addr = ai[0][-1]
    s.bind(addr)
    s.listen(0)

    s.setblocking(False)

    try:
        while True:
            client_socket, client_addr = None, None
            try: # Will fail if allready accepted socket
                client_socket, client_addr = s.accept()
            except:
                pass

            if client_socket:
                try: # Improve stability
                    answer_request(client_socket, client_addr)
                except:
                    try:
                        # Closing socket will fail if
                        # socket is allready closed.
                        client_socket.close_socket()
                    except:
                        pass
            time.sleep_ms(10)
    except:
        s.close()

main()
----------------------------
PC client

Code: Select all

Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> def client(ip='192.168.4.1', port=80):
...     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
...     s.connect((ip, port))
...     s.send(b'test client')
...     x = s.recv(1024)
...     print("reply:{}".format(x))
...
>>> client()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in client
ConnectionResetError: [WinError 10054] The remote host disconnect the connection.
On the MicroPython REPL, I got following:

Code: Select all

>>> import main_server
Bind address info: [(2, 1, 0, '', ('0.0.0.0', 80))]
add 1
aid 1
station: c0:38:96:92:9b:0f join, AID = 1
Request:
None
The "Request:" and "None" are executed by req = client_socket.readline(), which was None. And it was triggered by PC client for s.connect(), instead of s.send(). And for some reason, the server didn't write to connection anything and disconnect.

cefn
Posts: 230
Joined: Tue Aug 09, 2016 10:58 am

Re: Simple_web_server.py can not get remote request

Post by cefn » Mon Apr 02, 2018 12:47 pm

I haven't gone through testing your code, but readline waits for a newline character, which you didn't send from your client so there was no line to read.

Substitute the line...

Code: Select all

s.send(b'Hello\n')
...to send a newline.

https://docs.python.org/3.3/tutorial/inputoutput.html

Post Reply