Sockets - A few Questions

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Simon Knight
Posts: 919
Joined: Wed Nov 04, 2009 11:41 am

Sockets - A few Questions

Post by Simon Knight » Mon Jul 23, 2012 3:39 pm

Hi,
I am attempting to understand how sockets operate but I need some clarification. I have some code that starts listening on port 1987 :

Code: Select all

 accept connections on port 1987 with message NewConnection
I think this creates a socket which is allocated a unique number. When data arrives for the first time routine NewConnection is called. This routine announces the new connection and calls the routine ReadDataMessage e.g.

Code: Select all

on NewConnection s
   -- when a connection is recevied (this is first set up by mouseUp, above)
   -- the "s" variable contains the address and port of the computer that is connecting
   -- read in one line of data from the socket identified in the "s" variable
   put "NewConnection is called s = " & s & CR after fld "debug"
   read from socket s for 1 line
   put the result & CR after fld "debug"
    --remove any trailing return character
   put line 1 of it into tDataMessage
  
   
   put tDataMessage && "connected" & " on socket " & s & return & return after field "ServerMessages"
   -- start reading from the new connection contained in the "s" variable
   -- each time more data is received, call the chatMessage handler
   read from socket s with message ReadDataMessage
end NewConnection
(please excuse my debugging code)
My first question is where is the parameter "s" described in the documentation? It just seems to appear in the examples.

Code: Select all

on ReadDataMessage s,pdata
   -- this handler is called when new data is received from a client
-- it is first set up by the chatConnected handler above
-- the variable "s" contains the host and port of the computer sending
-- the variable "data" contains the text that they sent
   -- put the chat message and a new line after the main field
   put "ReadDataMessage is called " & CR after fld "debug"
   put fld "count" into tCount
   add one to tCount
   put tCount into fld "count"
   
   put pdata into theData
   put the last line of thedata into tdataline
   --put thedata & return & return after field "debug"
   put "Extracted : " & tdataline & return after field  "ServerMessages"
   put "End of Message " & return & return after field  "ServerMessages"
   
   -- call routines that process the message
  
  -- when more data is received from this client, send this message again
  read from socket s with message ReadDataMessage
end ReadDataMessage
Question two is why when this is run are multiple sockets listed by the opensockets command. It seems that each time my device communicates a new socket number is allocated i.e. NewConnection is being called more than once. Does this mean that I have failed to implement something in the client or is this expected performance? I have included some of the debug output which show the multiple socket numbers. Are they a bad thing ?
  • POST / HTTP/1.1
    connected on socket 10.0.2.3:42256
    Extracted : Test Message from Android
    End of Message
    POST / HTTP/1.1
    connected on socket 10.0.2.3:35194
    Extracted :
    End of Message
    Extracted : ,,,,,0,,,
    End of Message
    connected on socket 10.0.2.3:38830
    POST / HTTP/1.1
    connected on socket 10.0.2.3:34989
    Extracted : 1343052416,53.463578,-0.785349,50,53.400024,187.237265,-0.926184,7.600154,6.619489
    End of Message
    POST / HTTP/1.1
    connected on socket 10.0.2.3:33094
    Extracted : 1343052416,53.463578,-0.785349,50,53.400024,191.090762,-0.503953,6.714831,6.864655
    End of Message
My code is based on the iChat example stack.
Thanks for reading.
Simon
best wishes
Skids

BvG
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1239
Joined: Sat Apr 08, 2006 1:10 pm
Contact:

Re: Sockets - A few Questions

Post by BvG » Mon Jul 23, 2012 4:16 pm

All commands are fully explained not in the documentation, but in the online dictionary. For example the "accept" entry contains this:
The callbackMessage is sent to the object whose script contains the accept command. Either one or two parameters are sent with this message. The first parameter is the IP address of the system or process making the connection. If a datagram is being accepted, the second parameter is the contents of the datagram.
As for multiple connections, that is probably a problem with your client code, not the server code, can't be sure of course. It looks as if you're connecting with a webbrowser somehow?
Various teststacks and stuff:
http://bjoernke.com

Chat with other RunRev developers:
chat.freenode.net:6666 #livecode

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Sockets - A few Questions

Post by sturgis » Mon Jul 23, 2012 4:24 pm

Hey Simon,

While i'm not Mr Sockets i'll take a shot at this.

To see what parameter 's' represents look at the dictionary for accept.

From the dictionary:
The callbackMessage is sent to the object whose script contains the accept command. Either one or two parameters are sent with this message. The first parameter is the IP address of the system or process making the connection. If a datagram is being accepted, the second parameter is the contents of the datagram.
As for why a new socket appears every time a connection is made, you're using http post do do this since you're on android, this means its an open, send, close of the socket every time. Open socket listens on the specified socket, then when a connection request is received it creates a random high numbered (unused) socket for that specific connection and then keeps listening on the original socket for more connections, so the behavior you are seeing is correct. Each time you send a request a new socket must be assigned because the http post doesn't create a persistent socket.

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Sockets - A few Questions

Post by sturgis » Mon Jul 23, 2012 4:28 pm

sturgis wrote:Hey Simon,

While i'm not Mr Sockets i'll take a shot at this.

To see what parameter 's' represents look at the dictionary for accept.

From the dictionary:
The callbackMessage is sent to the object whose script contains the accept command. Either one or two parameters are sent with this message. The first parameter is the IP address of the system or process making the connection. If a datagram is being accepted, the second parameter is the contents of the datagram.
As for why a new socket appears every time a connection is made, you're using http post do do this since you're on android, this means its an open, send, close of the socket every time. Open socket listens on the specified socket, then when a connection request is received it creates a random high numbered (unused) socket for that specific connection and then keeps listening on the original socket for more connections, so the behavior you are seeing is correct. Each time you send a request a new socket must be assigned because the http post doesn't create a persistent socket.
EDIT: Ok, you didn't say android, but you did say device so i'm assuming either android or IOS so the explanation still applies. (if using a desktop machine then it would make sense to write a real sockets client)

Simon Knight
Posts: 919
Joined: Wed Nov 04, 2009 11:41 am

Re: Sockets - A few Questions

Post by Simon Knight » Mon Jul 23, 2012 5:50 pm

Hi, Thanks - I did not realise that there is an on line dictionary, but the description is also in the application dictionary, sorry - I'm off to the opticians for some new reading glasses :oops:

I'm attempting to send the GPS position on my Android phone to my laptop over wireless so the description of how Android works is spot on. Unfortunately the post command keeps blocking and timing out which is slowing the whole application down. i think I will have to sleep on it as I suspect I'm introducing more errors as I attempt to debug the code.

Are there any useful texts on how to set up server client communications using Livecode that you can recommend?

best wishes

Simon
best wishes
Skids

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Sockets - A few Questions

Post by sturgis » Mon Jul 23, 2012 6:07 pm

Do you send a post for every single locationchanged event? You might consider adding a time check so that if it hasn't been more than 500 milliseconds or so don't send another post to your laptop. I had to do this with the remote trackpad I setup to keep from overloading my laptop, and there was no need for the veritable fog of touchmove events. Tweak your timing as necessary.

As for the socket stuff, it sounds as though you are well on your way. Since there are no sockets on android or ios yet, using post or get to transfer your data is the way to go. (don't know which is faster, post or just using a url string and get.)

Since LC is single threaded you might also consider using an actual webserver for the back end, at which point rather than using post, you can use load with a callback (which you can do anyway come to think of it, single threaded or not) In this way you can do a non-blocking method with get, tack on the milliseconds as the last parameter for the url you are loading so that they are guaranteed to be unique (might not be an issue.)

In this way you can
EDIT:######### After thinking about it, this way is probably the way to go. You can still use your sockets stack most likely (though a webvserver would probably be more responsive) Load, when load is complete, respond and unload the url. Load is awesome and useful.

load URL "http://myurl.with.data:port/?param1=whatever&param2=whatever&themilliseconds=thecurrentmillseconds" with message "myUrlCallback"


Then in myUrlCallback process whatever is returned and unload the url. (You MUST unload it otherwise it stays in cache and after a bit your android will grind to a halt due to lack of memory)

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: Sockets - A few Questions

Post by mwieder » Mon Jul 23, 2012 6:11 pm

Simon-

Close the socket after reading the data. That should tell the client that the transaction is done. Otherwise the client will just hang there waiting for the end. I think that should take care of things for you.

Sturgis-

Spot-on socket transaction explanation.

Simon Knight
Posts: 919
Joined: Wed Nov 04, 2009 11:41 am

Re: Sockets - A few Questions

Post by Simon Knight » Mon Jul 23, 2012 9:20 pm

Hi,
At present I have reverted my client to just posting a short text message every second. My plan is to get this working reliably and then start adding the GPS data. I list the result of each post and I can see a number are timing out. One further source of confusion is that the socket numbers on the android client bear no resemblance to the sockets like numbers displayed as errors on the client.

You have given me some ideas - thanks. I'll report my progress.

Simon
best wishes
Skids

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: Sockets - A few Questions

Post by mwieder » Mon Jul 23, 2012 9:37 pm

I don't understand. You're seeing sockets on the Android client? Sockets aren't supported in that form on Android right now.

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Sockets - A few Questions

Post by sturgis » Mon Jul 23, 2012 9:56 pm

Simon is using Post to send data to a desktop server that is set to listen. (or get or load) Like you, i'm not sure where the socket numbers are coming from on the android side. Unless the server is returning info regarding the connection that the client is parsing.

Any chance you can post your client code Simon?

Simon Knight
Posts: 919
Joined: Wed Nov 04, 2009 11:41 am

Re: Sockets - A few Questions

Post by Simon Knight » Mon Jul 23, 2012 10:16 pm

Ah, I'll try (to post) but the pseudo socket numbers were appearing in an error message. I'll try and roll back to a version that was causing problems and post.

Moving on, I have removed the read command with a call to its self from ReadDataMessage and added a "close socket s" in its place. The server now displays all the messages sent to it with each message being associated with its own socket number. The client lists the result of each post and these are reported as "error" but I can live with that.

Thanks again for pointing me in the right direction. I'll post my code tomorrow once I've tidied it up and tested it a little more.

Simon
best wishes
Skids

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: Sockets - A few Questions

Post by mwieder » Mon Jul 23, 2012 10:26 pm

Just a WAG, but it sounds like you're getting an error on the client side because you're initiating an http transaction but the server end isn't doing its part. You might try responding to the client before closing the socket. The following code is taken from a working http server stack.

Code: Select all


...
server.SendHeader
server.SendBody "got the message!"
close socket sClientPort
...


command server.SendHeader
    write "HTTP/1.1 200 OK" & cr to socket sClientPort
    write "Content-Type:·text/html;·charset=UTF-8" & cr & cr to socket sClientPort
end server.SendHeader

command server.SendBody pBody
    write "<!doctype html>" & cr to socket sClientPort
    write "<html>" & cr to socket sClientPort
    write "<head></head>" & cr to socket sClientPort
    write "<body>" & pBody & "</body>" & cr to socket sClientPort
    write "</html>" & cr & cr to socket sClientPort
end server.SendBody

Simon Knight
Posts: 919
Joined: Wed Nov 04, 2009 11:41 am

Re: Sockets - A few Questions

Post by Simon Knight » Tue Jul 24, 2012 9:38 am

Hi,

This forum stales its users out rather to quickly, here is my second attempt at a post.

First please ignore all I wrote about socket numbers appearing in error messages on android, they did not.

Mark, thanks for the code snips which send responses back to the posting device - I hope these will remove the errors that I am seeing on the Android phone.

I have just reread the dictionary and wonder if my understanding is correct: The "accept" command opens the designated port e.g 1987 and this port will be listed as a socket by the "open sockets" command. Any communications on this port will be processed by the listening accept command which will create a new socket in the form portNo|SocketNo e.g. 1987|54321. This socket will stay live until it stales out (default 10 seconds) or it is closed. Some devices will address future communications to this socket but Android does not. It is wise to close sockets which are of no further use.

There is no opposite command to the accept "command" instead the command "close socket" is used with just the port number. I am not clear if closing the port also closes all live sockets on that port or if using the command with just an IP address closes all open ports: the documentation could be more detailed in this area.

thanks again for all the help given.

Simon
best wishes
Skids

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: Sockets - A few Questions

Post by mwieder » Tue Jul 24, 2012 5:44 pm

Your description sounds pretty close. A complication is that since we don't have sockets on the Android side, you're stuck with doing http transactions. And those have no history and are of the form

Code: Select all

open socket
post|get|put|delete data
close socket
So you can't reuse an open socket connection for more data transfers, as would be more normal with socket control on both sides. Instead this forces the opening of a new socket for each data transaction, and as you've noticed, the port numbers keep incrementing
I am not clear if closing the port also closes all live sockets on that port or if using the command with just an IP address closes all open ports: the documentation could be more detailed in this area.
I've never tried to close an IP address, so I don't know. But the "resetall" command is very handy - it will close all sockets that have been opened by LiveCode, so you can ensure that you don't have any strays left open.

Simon Knight
Posts: 919
Joined: Wed Nov 04, 2009 11:41 am

Re: Sockets - A few Questions

Post by Simon Knight » Tue Jul 24, 2012 7:37 pm

Hi,
I think I have created a correct server response using the following code:

Code: Select all

 --   --  Generates the HTTPd Header with a 200 OK response. (200 OK = Yes it succeded!)
     put "HTTP/1.1 200 OK" & crlf into tRetVal
     put "Content-Type: " & tType & crlf after tRetVal
     put "Connection: Close " & crlf after tRetVal
     put "Date: " & the date & the time & crlf after tRetVal
     put "Content-Length: " & tDataLength  & crlf after tRetVal
     put  crlf after tRetVal
     put tdataline & CRLF after tRetVal
   
     write tRetVal to socket s
If I run my client application as a desktop app it generates more error messages, using the response generated by the code above I get no errors and the data in tdataline is echoed on the client in the "it" variable of the post command.

The snag is that my client is still stalling. The routine with the post command is called a second after it finishes. I transmit 69 bytes (characters) every time the routine is called but it all stops after 80 odd iterations when running on Android, I'm pulling my hair out .

I've attempted to attach my two stacks in the hope that one of you experts can detect where I am going wrong.

Am I correct in thinking that I am unable to use UDP from an Android platform ?

best wishes
Simon
Attachments
AndroidSensorClient.livecode.zip
Android Client
(6 KiB) Downloaded 252 times
AndroidSensorServer.livecode.zip
The server
(6.29 KiB) Downloaded 245 times
best wishes
Skids

Post Reply