Re: Raspberry pi 4 GPIO ports control

Discussions related to network, internet and socket programming; also to serial, parallel, Bluetooth, USB etc.
Hated Moron

Re: Raspberry pi 4 GPIO ports control

Post by Hated Moron »

Ric wrote: Sat 11 Nov 2023, 13:12 This is the code, but i can see nothing wrong...
Look again, where is the path? :roll:

Code: Select all

  
  450   C% = OPENUP("testFile")
Because no path is specified the code is trying to open a file in the Current Directory, which I'm guessing you have never set. Therefore it's relying on pure luck that the Current Directory happens to be somewhere that you can legitimately store a file, which it may not be.

You might get away with it when running in the Windows IDE, although there's no guarantee, but you typically won't if you compile it to an EXE in Windows, and there's zero chance of it working in Android.

If it's a temporary file you should be putting it in @tmp$:

Code: Select all

  
  450   C% = OPENUP(@tmp$ + "testFile")
If it's a file which needs to be persistent you should be putting it in @usr$:

Code: Select all

  
  450   C% = OPENUP(@usr$ + "testFile")
I am assuming I have to do something different on a phone/tablet?
Not really, it just means that when writing cross-platform code you have to be even more careful than usual to follow the rules. What you might be able to get away with on one platform you may not be able to on another platform, but stick to the rules and you should be fine.
Ric
Posts: 200
Joined: Tue 17 Apr 2018, 21:03

Re: Raspberry pi 4 GPIO ports control

Post by Ric »

Thank you Richard,

I now have my Pi3 successfully connected as a client to the server, which now is either my laptop or phone depending on what i am doing.
The next step is to connect ten Pi3s to the server at once. As i understand it once the first client has connected to the server the connection then closes and can not be connected to by another client. I have tried and the second client says "cant connect to server". How do i go about connecting all the Pi3s. I presume polling is the answer, but do not know where to start. As always your help is greatly appreciated.

Kind regards Ric
Kind Regards Ric.

6502 back in the day, BB4W 2017 onwards, BBCSDL from 2023
Hated Moron

Re: Raspberry pi 4 GPIO ports control

Post by Hated Moron »

Ric wrote: Sun 12 Nov 2023, 12:33 How do i go about connecting all the Pi3s. I presume polling is the answer, but do not know where to start. As always your help is greatly appreciated.
I've not tried to do exactly that myself, so there's only a limited amount of advice I can give; you will need to take responsibility for the details of the design, it's called 'programming'! ;)

One fundamental decision you will need to make is whether your entire program can be synchronous, or whether you will need to incorporate asynchronous elements (for example an ON TIME handler). You can't really start constructing your program until you know that.

Fully-synchronous programs are safer and potentially more reliable, but can be messy unless the 'concurrent' tasks lend themselves to performing periodic polling. RISC OS programmers, forced to perform a regular Wimp_Poll, can attest to that!

Conversely an asynchronous approach can simplify the individual concurrent tasks, by avoiding the need for polling, but extreme care must be taken to eliminate subtle bugs resulting from the asynchronous nature of the process.

This won't necessarily be easy, but it should be rewarding. And frankly I'm desperate for this kind of expertise to be spread more widely, one of my greatest concerns is that in 2023, more than 22 years since BB4W was released, people are still asking me for advice. :shock:
Ric
Posts: 200
Joined: Tue 17 Apr 2018, 21:03

Re: Raspberry pi 4 GPIO ports control

Post by Ric »

Thanks but it didnt really answer my question.
At the moment i have only modified the client and server programs supplied.

If i use checkConnectionM in an otherwise unaltered program then I can get two clients to connect to the sever ( or at least i get no errors thrown back ), but only the first can talk to the server. Do i need to close the socket on the first client and re-establish with the second or is it possible to connect them both at the same time? When I try to connect them both the socket value returned in both client programs is the same so i assume this is not the way.

Kind regards Ric
Kind Regards Ric.

6502 back in the day, BB4W 2017 onwards, BBCSDL from 2023
Hated Moron

Re: Raspberry pi 4 GPIO ports control

Post by Hated Moron »

Ric wrote: Sun 12 Nov 2023, 14:56 Do i need to close the socket on the first client and re-establish with the second or is it possible to connect them both at the same time?
It should be possible to connect to them both at the same time, yes. As I mentioned before I've not personally tried it, so I can't be more specific (it's likely that the person who added FN_checkconnectionM() to the library has done it, but that wasn't me!).

But fundamentally I can't see why having multiple clients connected to the same server should be any different from having multiple servers connected to the same client, and that is something I've done (in my Inverter app) without any issues.

For my information, do you actually need to connect to multiple clients at the same time, or is it a short-lived 'batch' transaction which could acceptably be performed consecutively rather than concurrently?
DDRM

Re: Raspberry pi 4 GPIO ports control

Post by DDRM »

FWIW, and I'm dredging my memory of lectures from almost 3 years ago in Java, I think if you want multiple simultaneous connections to a server the server needs to be multi-threading, and handle each connection in a different thread. Typically it will listen on the public port, but then create a new thread (or use one from a pool), and hand the connection off to this thread, using a different port (thus freeing up the public "listening port" for a new connection to contact).

In Java at least, you also need to be careful to ensure that parallel threads are not trying to use the same memory/code at the same times!

Not sure if the BBC BASIC server code provides a way round those limitations.

Best wishes,

D
Hated Moron

Re: Raspberry pi 4 GPIO ports control

Post by Hated Moron »

DDRM wrote: Mon 13 Nov 2023, 08:52 I think if you want multiple simultaneous connections to a server the server needs to be multi-threading
I find that a rather strange and unhelpful comment. Of course it doesn't need multi-threading: nothing ever does, it's just one of several ways of achieving concurrency, and not one that is suited to BBC BASIC.

I said earlier in the thread that without a multi-threading capability the number of concurrent connections would be limited, but the OP explained that he needs only a few. I would guess that BBC BASIC could achieve a dozen or so without much effort (whereas multi-threading might achieve thousands).
Not sure if the BBC BASIC server code provides a way round those limitations.
BBC BASIC doesn't really support 'true' multi-threading at all. The closest you can get to that is to run multiple copies of the same program, thereby taking advantage of the Operating System's multi-tasking capability. That can be very effective (and easy) in some applications, but a network server isn't one of them because the OS is unlikely to let you open the same port on two or more processes.

So for a server written in BBC BASIC you are going to be limited to other ways of achieving concurrency (polling and asynchronous events being the two most obvious). But that should be perfectly adequate for the OP, given my understanding of his requirements. The very fact that the SOCKLIB library includes the FN_checkconectionM() function (added by a user who needed that capability) shows that multiple connections are possible.

I'm busy with other, more urgent, things at the moment; the release of BBCSDL v1.38a being top of the list. So I'm not going to volunteer to write the code the OP needs, but if he doesn't have the confidence to do so himself perhaps somebody else will offer to do it. it's a pity that Jon Ripley (author of webserver.bbc) is no longer around because I'm sure he would have found it quite straightforward.
Hated Moron

Re: Raspberry pi 4 GPIO ports control

Post by Hated Moron »

On 13/11/2023 17:42, Mark Moulding wrote (cross-posted from the Discussion Group):
The way that @DDRM has describes echos my experience writing a specialized web server in Microsoft Visual Basic....

Note that there is no need for multi-threading - although it can be done in VB6, it's quite a hassle, and quite unnecessary in most cases; the event-driven model works as well.
Exactly, multi-threading is one way to do it, and in many languages it is probably the best way, but it is not the only way.
It is necessary to monitor all active ports for data arrival; I could see doing this by attempting a non-blocking read on each active port in turn, but this seems like a very inefficient use of CPU. I expect that Richard can suggest a better way.
Not really. BBC BASIC is not an 'event driven' language, I doubt that the concept had even been devised in 1981! So the only practical way to implement concurrency is a polling method such as you describe. To get a feel for the potential inefficiency I've just done a quick test of how long FN_readsocket() takes on this PC, when there is nothing to receive; it appears to be around 60 μs.

Suppose there are 10 concurrent connections, and one wanted to poll them all every 10ms to check for incoming data, that would mean that about 600μs of that 10ms (6%) would be 'wasted' CPU time. I don't think that is too bad, but it does illustrate that the polling approach in an interpreted language like BBC BASIC will limit the number of concurrent connections significantly.
A very limited amount of state information needs to be maintained for each port, at least for a basic (lower case) web server, since HTML at its core is modeless
Indeed, but the OP is not using HTML and I have no idea what amount of state is needed per connection. But an array of structures is an elegant way of representing that state in BBC BASIC.
Regarding Richard's proposal and subsequent discard of multiple tasks to allow the operating system to handle multi-threading, would it be possible to have a master task listening to the primary port for connection requests, which then spawns additional tasks to complete the requests
I've not given it much thought, but I don't think that will work, with the existing SOCKLIB libraries anyway. When the 'listening' socket accepts an incoming connection request, it opens the socket which will be used for that connection, and I don't think there's any way to 'hand over' that socket from one process to another*.

* It appears that it is possible but one would have to bypass SOCKLIB to achieve that, and thereby lose the cross-platform compatibility.
Hated Moron

Re: Raspberry pi 4 GPIO ports control

Post by Hated Moron »

Just to make sure I'm not giving misleading information, I've just made a quick hack to 'server.bbc' to accept up to 4 concurrent connections rather than just one, and it works!

At the moment it's just one-way communication (client to server) but I can run 4 clients, connect them concurrently to the same server, type text into any of the clients and it appears at the server (I've divided the window into four columns, one for each connection).

This can't have taken more than about 30 minutes to code, so using a polling scheme to achieve concurrency really is as easy as I expected. Although not inherently very efficient, the server (connected to four clients) is still using well under 1% of the CPU on this Core i7 laptop.

The OP should be able to proceed with confidence that this technique will meet his needs.
Hated Moron

Re: Raspberry pi 4 GPIO ports control

Post by Hated Moron »

It's looking good. I've increased the number of concurrent connections to eight (and given each a different background colour for emphasis). Here's a screenshot of it in action, which needed most (but not all) of my networked computers turned on! The server is still (when idle, i.e. polling) taking less than 1% CPU.

All very straightforward, as I would have hoped. It would be interesting to see how many concurrent connections it could handle without the CPU load becoming excessive (with the 7 connections active, plus listening for one more, the profiler is reporting 92% of the time spent in the WAIT 1 statement which is determining the polling speed).

server_multi.png
You do not have the required permissions to view the files attached to this post.