ReceiveNetworkString()

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
MLK
Beiträge: 267
Registriert: 01.11.2004 13:17
Wohnort: Hamburg

ReceiveNetworkString()

Beitrag von MLK »

hier ist sie, meine erste assemblergeburt :allright:

mich hat an ReceiveNetworkData() so sehr gestört, dass man keine wirklich schöne rundum passende schleife basteln kann, dass ich mir nun mein eigenes ReceiveNetworkString() gebastelt habe. es benötigt NUR die ServerID und den *buffer, in welchen direkt geschrieben wird - nicht erst in einen zwischenbuffer. zu empfangen wird immer in der größe des verbleibenden *buffer-platzes versucht. die anzahl der schleifendurchläufe ist somit auf das absolute minimum begrenzt. rückgabewert ist die anzahl der empfangenen bytes.

Code: Alles auswählen

Procedure ReceiveNetworkString(ServerID, *Buffer)
	!ServerID	 equ Esp
	!Buffer		equ Esp + 4
	!Len			equ Esp + 8	
	!Result		equ Esp + 12
  
  Len.l
  
	!If ~ defined PB_Len | defined @f
      !extrn PB_Len
      !@@:
   !End If
         
   !If ~ defined _PB_ReceiveNetworkData@12 | defined @f
      !extrn _PB_ReceiveNetworkData@12
      !@@:
   !End If
               
   !MOV 	Eax, dword [Buffer]  
   !CALL	PB_Len  
   !MOV 	dword [Len], Eax
   !MOV	 dword [Result], Eax
   
   !@@:
      !PUSH		dword [Len]
      !PUSH		dword [Buffer + 4]
      !PUSH		dword [ServerID + 8]  
      !CALL		_PB_ReceiveNetworkData@12
      !CMP		 Eax, 0 
      !JE		  @f
      !SUB		 dword [Len], Eax  	
      !CMP		 dword [Len], 0
      !JE		  @f
      !ADD		 dword [Buffer], Eax	  		
      !JMP		 @b
   !@@:
   
   !MOV Eax, dword [Len]
   !SUB dword [Result], Eax
   
   ProcedureReturn Result
   !Restore ServerID
   !Restore Buffer
   !Restore Result
   !Restore Len 
EndProcedure
            
             
InitNetwork()
;
Host$ = "www.purearea.net"
;
If PeekL(PokeL(@ServerID, OpenNetworkConnection(Host$, 80))) = 0 : MessageRequester("", "cant't connect ''" + Host$ + "''") : End : Else
   If SendNetworkString(ServerID, "GET / HTTP/1.1" + #CRLF$ + "Host: " + Host$ + #CRLF$ + #CRLF$ )
      Response$ = Space(10000)
      MessageRequester(Str(ReceiveNetworkString(ServerID, @Response$)), Response$)
   EndIf
EndIf
man beachte die abfragen ob PB_Len und _ReceiveNetworkData bereits deklariert sind. "undefined symbol" oder "symbol already defined" - fehler gehören damit der vergangenheit an.


so, und jetzt huldigt mir! :wink:
Zuletzt geändert von MLK am 17.10.2005 23:04, insgesamt 2-mal geändert.
FloHimself
Beiträge: 338
Registriert: 05.09.2004 18:47

Beitrag von FloHimself »

nice!

ein vorschlag: benutze "local labels" oder "anonymous labels" in der
procedure. dann gibts kein ärger mit anderen labels im PB source.

vielleicht (nicht getestet):

Code: Alles auswählen

   !@@: 
      !PUSH      dword [Len] 
      !PUSH      dword [Buffer + 4] 
      !PUSH      dword [ServerID + 8]  
      !CALL      _PB_ReceiveNetworkData@12 
      !CMP       Eax, 0 
      !JE        @f
      !SUB       dword [Len], Eax      
      !CMP       dword [Len], 0 
      !JE        @f        
      !ADD       dword [Buffer], Eax            
      !JMP       @b
   !@@: 
Benutzeravatar
MLK
Beiträge: 267
Registriert: 01.11.2004 13:17
Wohnort: Hamburg

Beitrag von MLK »

yes! noch was schickes gelernt, danke. anonyme labels sind nicht nur besser, sondern wie ich finde auch viel handlicher. habe den code wie vorgeschlagen geändert. auch die beiden abfragen für den preprozessor sehen damit besser aus.
Antworten