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

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

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

Post by Dinosaur »

Hi All

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

Regards
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

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

Post by Dinosaur »

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: 8586
Joined: May 28, 2005 3:28
Contact:

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

Post by D.J.Peters »

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: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

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

Post by Dinosaur »

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: 8586
Joined: May 28, 2005 3:28
Contact:

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

Post by D.J.Peters »

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: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

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

Post by Dinosaur »

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: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

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

Post by Dinosaur »

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: 8586
Joined: May 28, 2005 3:28
Contact:

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

Post by D.J.Peters »

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: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

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

Post by Dinosaur »

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: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

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

Post by Dinosaur »

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: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

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

Post by Dinosaur »

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: 8586
Joined: May 28, 2005 3:28
Contact:

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

Post by D.J.Peters »

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: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

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

Post by Dinosaur »

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: 8586
Joined: May 28, 2005 3:28
Contact:

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

Post by D.J.Peters »

@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: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

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

Post by Dinosaur »

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
Post Reply