[S]imple [N]etwork [C]onnection win and lin 32/64-bit.

Post your FreeBASIC tips and tricks here. Please don’t post your code without including an explanation.
Dinosaur
Posts: 1126
Joined: Jul 24, 2005 1:13
Location: Searcy AR USA
Contact:

Re: [S]imple [N]etwork [C]onnection win and lin 32/64-bit.

Postby Dinosaur » Nov 04, 2015 3:44

Hi All

Thank you once again.
That tested perfectly.
I can now explode it into something usable and hopefully share.

Regards
Dinosaur
Posts: 1126
Joined: Jul 24, 2005 1:13
Location: Searcy AR USA
Contact:

Re: [S]imple [N]etwork [C]onnection win and lin 32/64-bit.

Postby Dinosaur » Nov 05, 2015 2:40

Hi All

Joshy I have converted the code into a module that I can use.
The idea is that I can't have any "While Wends" or sleeps or Do Loops.
The reason is that my TaskScan routine calls all the other machine control routines
one after the other.
Anyway, would love you to look it over and tell me where I got it wrong (It works)
or could be improved.

I will then do the same with the Server module.

Regards

Code: Select all

    'file: Ethclient.bas
    #include once "snc.bi"
Type EthClients
   StepNbr      as   Integer
   ErrCode      as  Integer
   ErrStep    as  Integer
   ErrMessage   as   ZString * 40
   StartTime   as   Double
   TargetIP   as   String  = "192.168.0.1"
   Port      as   Integer = 12345
   MesgLen      as   Integer
   Message      as  ZString * 80
   PortStatus   as   Integer
   Connection  as  Integer
End Type
Dim Shared EthClient as EthClients
Type Timing
    mSec      AS   UInteger
    OldmSec      As  UInteger
    StartTime   As  UInteger
    Raw         As  Double
    Increment   AS   Integer
    Debug      As  Integer            'Number to link routine name
    Loops      AS  Integer
    PassCount   AS  Integer
End TYPE                     
Dim Shared Times As Timing
Declare Sub Ethernet()
Declare Sub TimeShow()
Declare Sub TaskScan()
var shared Client = NetworkClient(EthClient.TargetIP,EthClient.PORT)

Sub Ethernet
   With EthClient
      Select Case .StepNbr
         Case -1
            'Wait here for other Routines to Instigate a Tx.
         Case 0
            .StepNbr = -1
         Case 1
            Locate 2,1:Print "Step:" & .StepNbr;
            var ErrorCode = Client.GetLastError()
            if ErrorCode <> ERROR_NO_ERROR then      'Problem
                  .ErrStep = 1
                  .StepNbr = 5
               Else                        'we are connected
                  .StepNbr    = 2         
                  .StartTime  = Times.mSec
            end if
         Case 2                              'Get Server connection
            Locate 3,1:Print "Step:" & .StepNbr;
            var Connection = Client.GetConnection()
            If (Connection = 0) And (Times.mSec - .StartTime > 10000) then
               .StartTime = Times.mSec
               .ErrStep = 1
               .StepNbr   = 5                  'Connection Failed during 10 Sec Wait
            End if
            If (Connection <> 0) then
               .StepNbr   = 3                  'Connection established
               .StartTime = Times.mSec
            End if
         Case 3
            Locate 4,1:Print "Step:" & .StepNbr;
            var Connection = Client.GetConnection()
            If  Connection->CanPut() <> 0 Then
               If Times.mSec - .StartTime > 100 then
                  .Portstatus = Connection->PutData(strptr(.Message),.MesgLen)
                  .StepNbr = 4
                  If .PortStatus < 0 then
                     .ErrCode = Client.GetLastError()
                     .ErrStep = 1
                     .StepNbr = 5
                  End If
               End if
            End If
         Case 4
            Locate 5,1:Print "Step:" & .StepNbr;
            If .Portstatus < 0 then .ErrCode = Client.GetLastError()
            If .ErrCode <> ERROR_NO_ERROR then
                  .StepNbr = 5            'Go Report the Error
                  .ErrStep = 1
               Else
                  .MesgLen = 0            'Clear Tx details
                  .Message = ""
                  .StepNbr = -1            'Go & wait for next time.
            End if
         Case 5
            Locate 6,1:Print "Step:" & .StepNbr;
            If .ErrCode <> ERROR_NO_ERROR then
               Locate 7,1:print "Error: " & GetNetworkErrorText(.ErrCode) & .ErrStep
            End if
            .StepNbr = -1
      End Select
   End With
End Sub
Sub TimeShow ()
    With Times
       .PassCount  += 1
       .Raw  = Timer      
       .mSec = CUInt(.Raw * 1000)
        '--------Scrn Refresh once every Sec.-----------
        If  .mSec >= (.OldmSec + 1000) Then                 'if 1 sec has elapsed
            .Increment  = (1000000 / .PassCount)            'uSec / passcount = uSec per program loop
            .OldmSec    = .mSec                             'save the ticks
            .PassCount  = 0                                 'reset Passcount
            Locate 1,1:Print Times.mSec, .Increment,.Passcount;
        EndIf
    End With
End Sub
Sub TaskScan
   'Main controller of all Tasks
   Do
      TimeShow
      Ethernet
      With EthClient   
         If .MesgLen > 0 then
            If .StepNbr = -1 then
               .StepNbr = 1
            End if
         End if
      End With
      If Inkey = "q" then exit do
   Loop
End Sub
   EthClient.StepNbr = 0
   EthClient.Message = "Test Message"
   EthClient.MesgLen = Sizeof(EthClient.Message) + 1
   TaskScan
   End

D.J.Peters
Posts: 7659
Joined: May 28, 2005 3:28

Re: [S]imple [N]etwork [C]onnection win and lin 32/64-bit.

Postby D.J.Peters » Nov 05, 2015 6:16

I found 3 errors and changed something search for !!!
(without my changes I never saw step 5 the error step of course I don't have your server running here)

Joshy

Code: Select all

     'file: Ethclient.bas
    #include once "snc.bi"
Type EthClients
    StepNbr     as  Integer
    ErrCode     as  Integer
    ErrStep     as  Integer
    ErrMessage  as  ZString * 40
    StartTime   as  Double
    TargetIP    as  String  = "192.168.0.1"
    'Port        as  integer = 12345  ' !!! not important but a network port is 16bit
    Port        as  ushort = 12345
    MesgLen     as  Integer
    Message     as  ZString * 80
    PortStatus  as  Integer
    Connection  as  NetworkConnection ptr ' !!! <-- added
End Type
Dim Shared EthClient as EthClients

Type Timing
    mSec        AS  UInteger
    OldmSec     As  UInteger
    StartTime   As  UInteger
    Raw         As  Double
    Increment   AS  Integer
    Debug       As  Integer             'Number to link routine name
    Loops       AS  Integer
    PassCount   AS  Integer
End TYPE                           
Dim Shared Times As Timing

var shared Client = NetworkClient(EthClient.TargetIP,EthClient.PORT)

Sub Ethernet
  With EthClient
    Locate .StepNbr+2,1
    Select Case .StepNbr
    Case -1
      ' Wait here for other Routines to Instigate a Tx.

    Case  0
      .StepNbr = -1

    Case  1 :
      Print "Step: 1"
      ' var ErrorCode = Client.GetLastError() ' !!! wrong must be .ErrCode
      .ErrCode = Client.GetLastError()
      if .ErrCode <> ERROR_NO_ERROR then     'Problem
        .ErrStep = 1
        .StepNbr = 5
      Else                                'we are connected
        .StepNbr    = 2       
        .StartTime  = Times.mSec
      end if

    Case 2 ' Get Server connection
      Print "Step: 2"
      ' var Connection = Client.GetConnection() !!! wrong to use a local var here
      .Connection = Client.GetConnection()  ' make it useable in next step 3
      If (.Connection = 0)  then' !!! changed the logic
        .StartTime = Times.mSec
        .ErrStep   = 1
        if (Times.mSec - .StartTime > 10000) then
          .StepNbr = 5 ' Connection Failed during 10 Sec Wait (!!! you go to error step 5 without an error code)
        else
          .StepNbr = 3 ' Connection established
        end if
      End if

    Case 3
      Print "Step: 3"
      ' you crerated a connection in step 2
      ' it makes no sence to create a second,a third ... connection here
      ' !!! var Connection = Client.GetConnection()
      If  .Connection->CanPut() <> 0 Then
        If Times.mSec - .StartTime > 100 then
          .Portstatus = .Connection->PutData(strptr(.Message),.MesgLen)
          .StepNbr = 4
          If .PortStatus < 0 then
            .ErrCode = Client.GetLastError()
            .ErrStep = 1
            .StepNbr = 5
          End If
        End if
      End If

    Case 4
      Print "Step: 4"
      If .Portstatus < 0 then
        .ErrCode = Client.GetLastError()
      end if
      If .ErrCode <> ERROR_NO_ERROR then
        .StepNbr = 5                'Go Report the Error
        .ErrStep = 1
      Else
        .MesgLen = 0                'Clear Tx details
        .Message = ""
        .StepNbr = -1               'Go & wait for next time.
      End if

    Case 5
      var msg = "Step: 5" ' !!!
      If .ErrCode <> ERROR_NO_ERROR then
        msg &= " ! " & GetNetworkErrorText(.ErrCode) & " !"
        .ErrCode=ERROR_NO_ERROR ' !!! it's more safe
      End if
      Print msg
      .StepNbr = -1
    End Select
  End With
End Sub

Sub TimeShow ()
  With Times
    .PassCount  += 1
    .Raw  = Timer     
    .mSec = CUInt(.Raw * 1000)
    '--------Scrn Refresh once every Sec.-----------
    If  .mSec >= (.OldmSec + 1000) Then                 'if 1 sec has elapsed
      .Increment  = (1000000 / .PassCount)            'uSec / passcount = uSec per program loop
      .OldmSec    = .mSec                             'save the ticks
      .PassCount  = 0                                 'reset Passcount
       Locate 10,1:Print Times.mSec, .Increment,.Passcount;
    else
       sleep 100 ' !!! don't eat all CPU time 10 times per second is OK
    End If
  End With
End Sub

Sub TaskScan
  'Main controller of all Tasks
  Do
   TimeShow
   Ethernet
   With EthClient
     If .MesgLen > 0 then
       If .StepNbr = -1 then .StepNbr = 1
     End if
   End With
   If Inkey = "q" then exit do
  Loop
End Sub

function main() as integer
  locate 0,0 : print"[q] = quit"
  EthClient.StepNbr = 0
  EthClient.Message = "Test Message"
  EthClient.MesgLen = Sizeof(EthClient.Message) + 1
  TaskScan
  return 0
end function

end main()
Dinosaur
Posts: 1126
Joined: Jul 24, 2005 1:13
Location: Searcy AR USA
Contact:

Re: [S]imple [N]etwork [C]onnection win and lin 32/64-bit.

Postby Dinosaur » Nov 05, 2015 21:58

Hi All

Joshy, once again, thank you.

The purpose of the way I wrote my part, is so that I can simply add the module to any of my projects.
All I have to do is set the .Message & .MesgLen anywhere in my application.
Because all my error handling is done by a dedicated module, I have eliminated all print statements,
but have added plenty of comments. (Mainly for me when I look at it again)

So, I tend to be slack about some things that I know I wont need after testing.
I have not fully accepted the "Pointers" feature in FB, and for that reason did not fully understand
your code until you corrected me.

But perhaps you have misunderstood my TimeShow routine.
It is just a central place to get the time (mSec) and once every Sec. do a calculation
to see how long it takes to scan all the routines once.
I am running this on a Mint Fit Pc ($200) and it takes 2 Micro Sec.

The TaskScan routine scans something like 20 routines (all using the same Select Case concept) and the I/O timing
that I have to maintain is within 1 mSec, so no sleeps.
And anyway, my application is the only thing running so not worried about starving other applications.

It looks like the Server will be an easier job to do, but will post here as well when done.

Regards

If you run this without the server, you should get the Fatal Error message.

Code: Select all

    'file: Ethclient.bas
    #include once "snc.bi"
Type EthClients
   StepNbr      as   Integer
   ErrCode      as  Integer
   ErrStep    as  Integer
   ErrFatal   as   Integer
   ErrCount   as   Integer
   ErrMessage   as   ZString * 40
   StartTime   as   Double
   TargetIP   as   String  = "192.168.0.1"
   Port      as   UShort = 12345
   MesgLen      as   Integer                  'Calc. by other Function
   Message      as  ZString * 80            'Set   '    '    '    '
   PortStatus   as   Integer
   Connection  as  NetworkConnection Ptr
End Type
Dim Shared EthClient as EthClients
Type Timing
    mSec      AS   UInteger
    OldmSec      As  UInteger
    StartTime   As  UInteger
    Raw         As  Double
    Increment   AS   Integer
    Loops      AS  Integer
    PassCount   AS  Integer
End TYPE                     
Dim Shared Times As Timing
Declare Sub Ethernet()
Declare Sub TimeShow()
Declare Sub TaskScan()
var shared Client = NetworkClient(EthClient.TargetIP,EthClient.PORT)

Sub Ethernet
   With EthClient
      Select Case .StepNbr
         Case -1
            'Wait here for other Routines to Instigate a Tx.
         Case 0
            .StepNbr = -1
         Case 1
            .ErrCode = Client.GetLastError()
            if .ErrCode <> ERROR_NO_ERROR then   
                  .ErrStep = 1         'Problem
                  .StepNbr = 5
               Else                  'we are connected
                  .StepNbr    = 2         
                  .StartTime  = Times.mSec
            end if
         Case 2                        'Get Server connection
            .Connection = Client.GetConnection()
            If (.Connection = 0)  Then
               .ErrStep = 1
               If (Times.mSec - .StartTime > 10000) then
                     .StepNbr   = 5      'Connection Failed
                  Else               'during 10 Sec Wait
                     .StepNbr = 3
               End if
            End if
            If (.Connection <> 0) then
               .StepNbr   = 3            'Connection established
               .StartTime = Times.mSec
            End if
         Case 3                        'Send Data
            If .Connection->CanPut() <> 0 Then
               If Times.mSec - .StartTime > 100 then
                  .Portstatus = .Connection->PutData(strptr(.Message),.MesgLen)
                  .StepNbr = 4
                  If .PortStatus < 0 then
                     .ErrCode = Client.GetLastError()
                     .ErrStep = 1
                     .StepNbr = 5
                  End If
               End if
            End If
         Case 4
            If .Portstatus < 0 then .ErrCode = Client.GetLastError()
            If .ErrCode <> ERROR_NO_ERROR then
                  .StepNbr = 5         'Go Report the Error
                  .ErrStep = 1
               Else
                  .MesgLen = 0         'Clear Tx details
                  .Message = ""
                  .StepNbr = -1         'Go & wait for next time.
            End if
         Case 5
            If .ErrCode <> ERROR_NO_ERROR then
               .ErrCount += 1
               .ErrMessage = GetNetworkErrorText(.ErrCode)
               If .ErrCount >= 10 then
                  .ErrFatal = 1
                  .ErrMessage = "To many Errors: Connect attempt halted"
               End If
            End if
            .ErrCode = Error_No_Error
            .StepNbr = -1
      End Select
   End With
End Sub
Sub TimeShow ()
    With Times
       .PassCount  += 1
       .Raw  = Timer      
       .mSec = CUInt(.Raw * 1000)
        If  .mSec >= (.OldmSec + 1000) Then      'if 1 sec has elapsed
            .Increment  = (1000000 / .PassCount) 'uSec / passcount = uSec per loop
         'print .Increment if you want to see your Loop time in micro-sec's
            .OldmSec    = .mSec                  'save the ticks
            .PassCount  = 0                      'reset Passcount
        EndIf
    End With
End Sub
Sub TaskScan
   'Main controller of all Tasks
   Do
      TimeShow
      Ethernet
      With EthClient   
         If .ErrFatal < 1 then            'If no Fatal Error
               If .MesgLen > 0 then      'and a message is loaded
                  If .StepNbr = -1 then   'and Client is NOT busy
                     .StepNbr = 1      'hand over the job.
                  End if
               End if
               If .ErrMessage <> "" then   'Less then Fatal error
                  Print .ErrMessage      'Delete this line to       
                  .ErrMessage = ""      'print to ErrControl Routine.
               End If
            Else
               If .ErrCount > 0 then      'When Fatal & Count not cleared yet
                  Print .ErrMessage      'Delete this line ........
                  .ErrCount = 0         'we wont try to connect again.
               End If                  'cause .Fatal remains set.
         End If
      End With
      If Inkey = "q" then exit do
   Loop
End Sub
Function Main() as Integer
   '--------------------------------------
   'When patching the above into other projects
   'delete this Function
   '--------------------------------------
   Locate 1,1:Print "Press [q] to Quit"
   EthClient.StepNbr = 0
   EthClient.Message = "Test Message"
   EthClient.MesgLen = Sizeof(EthClient.Message) + 1
   TaskScan
   Return 0
End Function
End Main()

D.J.Peters
Posts: 7659
Joined: May 28, 2005 3:28

Re: [S]imple [N]etwork [C]onnection win and lin 32/64-bit.

Postby D.J.Peters » Nov 06, 2015 0:39

You use a kind of state machine (turing machine)
it's OK but not if it eats all CPU power while it waits for a new step.

I showed you only your bugs.

var ErrCode is a different var as your defined member var .ErrCode

case X:
var connection = NewConnection
case Y:
var connection = NewConnection

Creates two different connection (new is used in "snc.bi")
on end of an scope (case is an scope also) the var will be destroyed and the destructor in "snc.bi" are called.

bla bla bla :-)

Joshy
Dinosaur
Posts: 1126
Joined: Jul 24, 2005 1:13
Location: Searcy AR USA
Contact:

Re: [S]imple [N]etwork [C]onnection win and lin 32/64-bit.

Postby Dinosaur » Nov 06, 2015 16:32

Hi All

Joshy I appreciate your patience.

Solving one anomaly at a time, is this a better solution ? (it seems to work but may be wrong)

Code: Select all

Type EthClients
....
    ErrCode as NetWork_Error
....
End Type

Regards
Dinosaur
Posts: 1126
Joined: Jul 24, 2005 1:13
Location: Searcy AR USA
Contact:

Re: [S]imple [N]etwork [C]onnection win and lin 32/64-bit.

Postby Dinosaur » Nov 07, 2015 18:20

Hi All

Joshy, one thing I don't understand (well at least one that bothers me).

When I make a connection at the client with the server, what is done to Terminate the connection ?
Do I need to issue a statement to break the connection, or is the connection terminated
when the ->PutData is finished, and thus frees up the server for another connection.?

Regards
D.J.Peters
Posts: 7659
Joined: May 28, 2005 3:28

Re: [S]imple [N]etwork [C]onnection win and lin 32/64-bit.

Postby D.J.Peters » Nov 07, 2015 18:35

Why you don`t show in snc.bi or on first page of this thread '

The class NetworkConnection has an destructor inside the destructor the socket are closed.

All destructors from active instances are called if your program ends or you delete the class self.

Code: Select all

destructor NetworkConnection.
  if sock<>-1 then
    closesocket(sock)
    sock=-1
  end if
end destructor
Dinosaur
Posts: 1126
Joined: Jul 24, 2005 1:13
Location: Searcy AR USA
Contact:

Re: [S]imple [N]etwork [C]onnection win and lin 32/64-bit.

Postby Dinosaur » Nov 07, 2015 18:43

Hi All

Why you don`t show in snc.bi or on first page of this thread '

Very simple, because I have never used or called a destructor in all my time of using FreeBasic.

Regards
Dinosaur
Posts: 1126
Joined: Jul 24, 2005 1:13
Location: Searcy AR USA
Contact:

Re: [S]imple [N]etwork [C]onnection win and lin 32/64-bit.

Postby Dinosaur » Nov 12, 2015 3:35

Hi All

After a week or more of modifying code, I am finally getting the hang of it.
Firstly I over complicated the the whole thing, because of my timing issues.
However, I concluded that the only time a transmission was called for,
was when the critical timing issues were stopped.
So, I restarted and simplified the code, so a single call to the Ethernet Function does the job.

Code: Select all

'-----------------------------------------------------------------------
Function Ethernet as Integer
   With EthClient
      var TxData = .Message
      var Client = NetworkClient(.TargetIP,.PORT)
      var errorcode = Client.GetLastError()
      If errorcode then
         .ErrCode = errorcode
         Return .ErrCode
      End if
      var Connection = Client.GetConnection()
      while Connection->CanPut()=0
         sleep 100
      wend
      var size = len(.Message)+1
      If Connection->CanPut() > 0 Then
         var Status = Connection->PutData(strptr(.Message),size)   
         If Status < 1 Then
            var errorcode = Client.GetLastError()
            if errorCode <> ERROR_NO_ERROR then   
               .ErrMessage = GetNetworkErrorText(errorcode)
               .ErrCode = ErrorCode
               Return .ErrCode
            end if
         End if
      End if
   End With
   Return 0
End Function

The same with the Server, which does not have any time critical functions anyway.

Code: Select all

Sub Ethernet 
   With EthServer
      var Connection = Server.GetConnection()
      Locate 1,1:Print Connection
      if Connection > 0 then   
         while Connection->CanGet()=0
            Sleep 100
         Wend
         If Connection->CanGet() > 0 Then      
            var status = Connection->GetData(.Message)
            If .Message then
               .RxData  = *.message
               .MesgLen = Len(.RxData)
            End if
         End If
      End if   
   End With
End Sub

Between these two I am happy that it all works.
The only error I have had seems to be a clash between my WiFi Internet and the hard cabled Ethernet.(Server)
The client could not connect, and the Server just sat there waiting for a connection.
But by disabling the WiFi, that problem went away.
Where it will be installed there wont be an Internet connection.

After being so impressed by it, I decided that perhaps I can use this for a command exchange between one of 3 Clients
and a single server.(Instead of hard wiring I/O)
ie: Command, SubCommand, Value

So, now the question:
What difficulties am I going to experience in clashes (or none) between 3 Clients sending to a single server via a switch.
Typically each one may create a transmission once every 2 minutes, but Murphy's Law says that two of them will
try at exactly the same time.

EDIT: Timing an exchange resulted in generally less then 1mSec for an 80 char string.


Regards
Dinosaur
Posts: 1126
Joined: Jul 24, 2005 1:13
Location: Searcy AR USA
Contact:

Re: [S]imple [N]etwork [C]onnection win and lin 32/64-bit.

Postby Dinosaur » Nov 14, 2015 15:32

Hi All

Joshy, how do I send a response from Server to Client after the Server receives the client message.
Is that done on the same Connection or do I have to start a complete new connection on both.?

Obviously the server needs to know the IP of the client to send to.

Regards
D.J.Peters
Posts: 7659
Joined: May 28, 2005 3:28

Re: [S]imple [N]etwork [C]onnection win and lin 32/64-bit.

Postby D.J.Peters » Nov 14, 2015 16:06

A network connection is a two way data link independently is it a server or client connection.
You can put/get data on the same connection.

The primary difference are a server can have # numbers connection (one per client)
and a client has only one connection to the server.

You got it now ?

Joshy

edit: (and sorry about my bad english)
In your case the server acts like a modem right ?
That means your server has only one connection to one client at same time.

It makes no sense if your server are busy to allow more clients to connect.
If a second or third clients try to connect while your server are busy ignore it.
In this case a client try to connect later again, again is depently from how long your server needs for one modem transmission.
5,10,30 seconds or 1,2 ... minutes ... ?

It will be much more complex if you allow more than one client connection at same time if your server are busy.
You have to manage a list of waiting clients or you create a parallel running server thread per client.
If you are an beginner in programming I would prefer ignore more than one client connection.

Your other hardware the modem you are talked in the past is a single instance hardware.
That means you have to be shure that only one server thread is using it.
The keywords to handle it are THREAD , MUTEX and last but not least CONDITION.
Dinosaur
Posts: 1126
Joined: Jul 24, 2005 1:13
Location: Searcy AR USA
Contact:

Re: [S]imple [N]etwork [C]onnection win and lin 32/64-bit.

Postby Dinosaur » Nov 14, 2015 18:43

Hi All

Joshy, thanks for the reply.
If you are an beginner in programming I would prefer ignore more than one client connection.
I am not a beginner but a "Traditional" programmer in both Assembly Language & Basic since 1970.
Always single thread, never use shortcuts always the long instructions.
That's why I am a Dinosaur.
You can put/get data on the same connection.
That is where I am stuck.
Are you saying I can do this :

Code: Select all

   var Connection = Server.GetConnection()
   With Ethernet
      if Connection > 0 then
         while Connection->CanGet() = 0
            Sleep 100
         Wend
         If Connection->CanGet() > 0 Then      
            var status = Connection->GetData(.Message)
            If .Message then
               .RxData  = *.message
               Print .RxData
               .MesgLen = Len(.RxData)
            End if
                    End if
         If Connection->CanPut() > 0 then
            var Size = Len(.TxData) + 1
            var Status = Connection->PutData(StrPtr(.TxData),Size)
            If Status = Len(.TxData) + 1 then
               'Got sent OK
            Endif
         End if            
      End If
   End With


You are right about single connection, I will complete one connection before looking for another.

Regards

EDIT: I have been trying the above method for two days now, but thought I was doing something wrong
because the Time taken was so long.
Client : Tx = less then 1 mSec, Rx = 2146 mSec
Server: Rx = 1035 mSec , Tx = less then 1 mSec
So in both cases the receiving time is more then 1 or 2 sec's ????
D.J.Peters
Posts: 7659
Joined: May 28, 2005 3:28

Re: [S]imple [N]etwork [C]onnection win and lin 32/64-bit.

Postby D.J.Peters » Nov 14, 2015 21:46

@Dino :-) you are right the brake to get data from connection isn't normal.
I must do a deeper look at file "snc.bi" to find the bastardo ;-)

Joshy

Code: Select all

#include once "snc.bi"

const PORT = 12345

const DATASIZE = 1024*256 ' 256 KB
dim as ubyte ptr pData,pDatapacket = allocate(DATASIZE)

var t = timer()
var Server = new NetworkServer(PORT)
t=timer()-t
print "time to create a local server: " & t

t=timer()
var Client = new NetworkClient("127.0.0.1",PORT)
t=timer()-t
print "time to create a local client: " & t


t=timer()
var ToClient = Server->getConnection()
t=timer()-t
print "time to get client connection: " & t

t=timer()
var ToServer = Client->getConnection()
t=timer()-t
print "time to get server connection: " & t

print "mensured data tranfer rate"
dim as double tPut,tGet
t=timer()

dim as integer processed,nbytes
while processed<1024*1024 ' 1 MB
  tPut=timer()
  nBytes = ToServer->PutData(pDatapacket,DATASIZE)
  tPut=timer()-tPut
  print "time to put: " & tPut
  tGet=timer()
  nBytes=ToClient->GetData(pData)
  tGet=timer()-tGet
  print "time to get: " & tGet
  processed+=nBytes
wend
t=timer()-t
print
print "time to send and receive 1 MB in packages of 256 KB: " & t
print "done ..."

delete client
delete server

sleep
Dinosaur
Posts: 1126
Joined: Jul 24, 2005 1:13
Location: Searcy AR USA
Contact:

Re: [S]imple [N]etwork [C]onnection win and lin 32/64-bit.

Postby Dinosaur » Nov 14, 2015 23:27

Hi All

Joshy, I think the problem happens when I set ReplyDue to 1 in the code below.
It appears that as soon as I attempt Connection->CanGet the previously sent TxData is interupted
and the time becomes longer.
I have tried putting 1sec delay before it, but no difference.
Note that I agree with the error checking but while testing I have removed a lot so it is easier to read.

Code: Select all

Function EthClient() as Integer
   With Ethernet
      var TxData = .TxData
      var size = Len(TxData) + 1
      If Size > 1 then
         var Client = NetworkClient(Ethernet.TargetIP,Ethernet.PORT)
         var Connection = Client.GetConnection()
         If Connection > 0 then
            While Connection->CanPut = 0
               Sleep 100
            Wend
            If Connection->CanPut() > 0 then
               var Status = Connection->PutData(StrPtr(TxData),Size)
               If Status <> Len(TxData) + 1 then
                     var errorcode = Client.GetLastError()
                     if errorCode <> ERROR_NO_ERROR then   
                        .ErrMessage = GetNetworkErrorText(errorcode)
                        .ErrCode = ErrorCode
                        Return .ErrCode
                     end if         
                  Else
                     .TxData = ""
                     Size = 0
               Endif
            End if
            '--Code below interupts Server Receiving TxData from above
            If .ReplyDue > 0 Then
               While Connection->CanGet = 0
                  Sleep 100
               Wend
               If Connection->CanGet() > 0 Then
                  var status = Connection->GetData(.RxPtr)
                  If .RxPtr then
                     .RxData   = *.RxPtr
                     .MesgLen  = Len(.RxData)
                     .ReplyDue = 0
                     Print .RxData
                     Return 0
                  End if
               End If
            End If
         End If
      End if
   End With
End Function


Here is my Server Sub.

Code: Select all

Sub EthRx ()
   var Connection = Server.GetConnection()
   With Ethernet
      if Connection > 0 then
         Times.Raw  = Timer      
         Times.StartTime = CUInt(Times.Raw * 1000)
         while Connection->CanGet() = 0
            Sleep 100
         Wend
         If Connection->CanGet() > 0 Then      
            var status = Connection->GetData(.MesgPtr)
            If .MesgPtr then
               .RxData  = *.mesgPtr
               .MesgLen = Len(.RxData)
            End if
         End If
         Times.Raw  = Timer      
         Print "Rx Time;";CUInt(Times.Raw * 1000) - Times.StartTime
         '----------If first Chr = 2 then a Reply is needed----------
         Times.Raw = Timer
         If Left(.RxData,1) = "2" then
               Times.StartTime = CUInt(Times.Raw * 1000)
               while Connection->CanPut() = 0
                  Sleep 100
               Wend
               If Connection->CanPut() > 0 then
                  var Size = Len(.TxData) + 1
                  var Status = Connection->PutData(StrPtr(.TxData),Size)
                  If Status = Len(.TxData) + 1 then
                     Times.Raw  = Timer      
                     Print "Tx Time;";CUInt(Times.Raw * 1000) - Times.StartTime
                  Endif
               End if            
         End If
      End If
   End With
End Sub


My result of your test
time to create a local server: 2.204230986535549e-05
time to create a local client: 0.0003269430017098784
time to get client connection: 1.107668504118919e-05
time to get server connection: 1.049484126269817e-06
mensured data tranfer rate
time to put: 0.0001830823021009564
time to get: 1.657788963173516
time to put: 0.0003290807362645864
time to get: 1.661331954412162
time to put: 0.0002439605304971337
time to get: 1.661802023183554
time to put: 0.0001430803677067161
time to get: 1.659845988499001

time to send and receive 1 MB in packages of 256 KB: 6.642125082318671
done ...

Regards

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 3 guests