B4R Question B4R Sockets, Astreams, initialize, errors. 8266 wifi

RJB

Active Member
Licensed User
Hi,
some points/ queries:
I assume that you do not initialize sockets in B4R as there is no socket.initialize.
I also assume that there is no Socket_Connected (Successful As Boolean) as that doesn't seem to trigger? (I'm using Socket.Connected to see if it safe to send, is that the correct approach?)
Astream_Error seems to trigger for each Astreams.Write. Is that correct? If not then what could cause it to do so? Without any debugging support I can't find the cause.
Thanks
 

Erel

Administrator
Staff member
Licensed User

RJB

Active Member
Licensed User
Hi,
Thanks
Looking at the example there is no .initialize so you go directly to .connect[IP or Host] and you loop around the .connect until it returns True, which seems sensible, though I might set a counter to exit if there's a problem causing it to fail permanently!
In the expected outputs:
B4X:
1
192.168.4.1
192.168.4.1
0.0.0.0
new connection
new data: hello!!!
error
new connection
new data: hello!!!
error
new connection
new data: hello!!!
error
and
B4X:
1
192.168.4.2
Trying to connect
connected
error
it does look like Astream_Error is being called each time, or am I miss-reading it?
thanks
 

RJB

Active Member
Licensed User
Also: using prefix mode at both ends - the data does get through, even though there is the call to _Error!
 

RJB

Active Member
Licensed User
Hi,
is the call to _error each time normal/ to be expected?
is there actually any use for the _error sub if it's called every time and there's no way to find out why?
B4X:
[/COLOR][/FONT][/LEFT]
1
192.168.4.1
192.168.4.1
0.0.0.0
new connection
new data: hello!!!
error                    <----------------
new connection
new data: hello!!!
error                    <----------------
new connection
new data: hello!!!
error                    <----------------
[LEFT][FONT=verdana][COLOR=rgb(20, 20, 20)]
 

RJB

Active Member
Licensed User
It's the two in your example, as given in the link above:

Server:
B4X:
Sub Process_Globals
   Public Serial1 As Serial
   Private wifi As ESP8266WiFi
   Private server As WiFiServerSocket
   Private astream As AsyncStreams
End Sub
Private Sub AppStart
   Serial1.Initialize(115200)
   Log("AppStart")
   Log(wifi.StartAccessPoint("esp_server"))
   Log(wifi.AccessPointIp)
   RunNative("SetAP", Null)
   Log(wifi.AccessPointIp)
   Log(wifi.LocalIp)
   server.Initialize(51042, "server_NewConnection")
   server.Listen
End Sub

#if C
void SetAP(B4R::Object* o) {
   WiFi.mode(WIFI_AP);
}
#end if
Sub Server_NewConnection (NewSocket As WiFiSocket)
   astream.InitializePrefix(NewSocket.Stream, False, "astream_NewData", "astream_Error")
   Log("new connection")
End Sub
Sub astream_NewData (Buffer() As Byte)
   Log("new data: ", Buffer)
   server.Socket.Close 'disconnect to allow new connections
End Sub
Sub astream_Error
   Log("error")
   server.Listen
End Sub
Client:
B4X:
Sub Process_Globals
   Public Serial1 As Serial
   Private wifi As ESP8266WiFi
   Private socket As WiFiSocket
   Private astream As AsyncStreams
End Sub

Private Sub AppStart
   Serial1.Initialize(115200)
   Log("AppStart")
   RunNative("SetSTA", Null)
   Log(wifi.Connect("esp_server"))
   Log(wifi.LocalIp)
   Connect(0)
End Sub

Sub Connect(u As Byte)
   Log("Trying to connect")
   If socket.ConnectIP(Array As Byte(192, 168, 4, 1), 51042) Then
       Log("connected")
       astream.InitializePrefix(socket.Stream, False, "astream_NewData", "astream_Error")
       astream.Write("hello!!!")
   Else
       CallSubPlus("Connect", 1000, 0)
   End If
End Sub


#if C
void SetSTA(B4R::Object* o) {
   WiFi.mode(WIFI_STA);
}
#end if

Sub astream_NewData (Buffer() As Byte)
   Log("new data: ", Buffer)
End Sub

Sub astream_Error
   Log("error")
End Sub
 

Erel

Administrator
Staff member
Licensed User
Check the server code. It closes the socket after it receives the data. Remove that line.
 

RJB

Active Member
Licensed User
That stops the error at the client end but it's still there at the server end.
 

Erel

Administrator
Staff member
Licensed User
You are doing something wrong. Check your code carefully. Add some logs to better understand what happens. If you are unable to find it then upload the updated projects.
 

RJB

Active Member
Licensed User
Hi,
I've put a timer in the client end to repeatedly call the Connect sub.
At the Server I've put and logs at the end of the _Newdata sub and the beginning of the _NewConnection sub.
_error seems to be called when _NewConnection even is raised.
 

Erel

Administrator
Staff member
Licensed User
You still haven't uploaded your code.

I've put a timer in the client end to repeatedly call the Connect sub.
Sounds like a mistake. This will cause the previous connection to break.
 

RJB

Active Member
Licensed User
The problem is shown in your code in your example at https://www.b4x.com/android/forum/threads/connecting-two-esp8266-boards.89726/#content.
The error events are clearly shown, as indicated by the arrows in #5 above. This is your expected logs from the same link.
I removed the server socket close as recommended by you in #10 above. This stopped the 'errors' in the client logs but leaves the socket open, so does that cause problems later?
So the client code is your code modified as follow with a timer. The timer is set to 10s to allow plenty of time between calls to Connect.
B4X:
Sub Process_Globals
   Public Serial1 As Serial
   Private wifi As ESP8266WiFi
   Private socket As WiFiSocket
   Private astream As AsyncStreams
   Dim Timer1 as Timer
End Sub

Private Sub AppStart
   Serial1.Initialize(9600) '115200)
   Log("AppStart")
   RunNative("SetSTA", Null)
   Log(wifi.Connect("esp_server"))
   Log(wifi.LocalIp)
   'Connect(0)
   Timer1.Initialize("Timer1_Tick", 1000)
   Timer1.Enabled = True
End Sub

Sub Timer1_Tick
   Connect(0)
End Sub

Sub Connect(u As Byte)
   Log("Trying to connect")
   If socket.ConnectIP(Array As Byte(192, 168, 4, 1), 51042) Then
       Log("connected")
       astream.InitializePrefix(socket.Stream, False, "astream_NewData", "astream_Error")
       astream.Write("hello!!!")
'   Else
'       CallSubPlus("Connect", 1000, 0)
   End If
End Sub


#if C
void SetSTA(B4R::Object* o) {
   WiFi.mode(WIFI_STA);
}
#end if

Sub astream_NewData (Buffer() As Byte)
   Log("new data: ", Buffer)
End Sub

Sub astream_Error
   Log("error")
End Sub
I modified your Server code with some log statements as follows:
B4X:
Sub Process_Globals
   Public Serial1 As Serial
   Private wifi As ESP8266WiFi
   Private server As WiFiServerSocket
   Private astream As AsyncStreams
End Sub
Private Sub AppStart
   Serial1.Initialize(9600) '115200)
   Log("AppStart")
   Log(wifi.StartAccessPoint("esp_server"))
   Log(wifi.AccessPointIp)
   RunNative("SetAP", Null)
   Log(wifi.AccessPointIp)
   Log(wifi.LocalIp)
   server.Initialize(51042, "server_NewConnection")
   server.Listen
End Sub

#if C
void SetAP(B4R::Object* o) {
   WiFi.mode(WIFI_AP);
}
#end if
Sub Server_NewConnection (NewSocket As WiFiSocket)
log("New connection")
   astream.InitializePrefix(NewSocket.Stream, False, "astream_NewData", "astream_Error")
End Sub
Sub astream_NewData (Buffer() As Byte)
   Log("new data: ", Buffer)
 Log("New data end")
   'removed at Erel's suggestion server.Socket.Close 'disconnect to allow new connections
End Sub
Sub astream_Error
   Log("error")
   server.Listen
End Sub
at the client end the logs are:
B4X:
Trying to connect
connected
Trying to connect
connected  ……. etc.
at the server:
B4X:
HpY�$$rz�4C8R��AppStart
1
192.168.4.1
192.168.4.1
(IP unset)
new connection
new data: hello!!!
New data end
error
new connection
new data: hello!!!
New data end
error
new connection
new data: hello!!!
New data end  ………..etc.
 
Last edited:

Erel

Administrator
Staff member
Licensed User
The problem is shown in your code in your example
It is not a problem in my example. The socket is closed by design after the message is received. This is a useful and reliable way for communication that doesn't require maintaining a connection. This is how Http (1.0) works.
If you only need to send a single message each time then closing the socket as soon as possible is a good solution.

I don't see why the client timer is needed. Looks like a mistake to me.
Overall the code is quite simple. I'm not sure what is the question and which problem you are trying to solve. Maybe better to start with a new thread and provide more information about your use case.
 

RJB

Active Member
Licensed User
Perhaps I'm asking the wrong question.
All I wanted to know is why, in the example code, Astream_Error is called each time? As shown in the "expected outputs" from the example, arrowed below?

B4X:
1
192.168.4.1
192.168.4.1
0.0.0.0
new connection
new data: hello!!!
error                    <----------------
new connection
new data: hello!!!
error                    <----------------
new connection
new data: hello!!!
error                    <----------------
 

RJB

Active Member
Licensed User
Perhaps I'm asking the wrong question.
All I wanted to know is why Astream_Error is called each time, in the example code as shown arrowed below in the "expected outputs"

server:
B4X:
1
192.168.4.1
192.168.4.1
0.0.0.0
new connection
new data: hello!!!
error                    <----------------
new connection
new data: hello!!!
error                    <----------------
new connection
new data: hello!!!
error                    <----------------
client:
B4X:
1
192.168.4.2
Trying to connect
connected
error     <---------------
 
Top