UDP.pbi für Linux

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
Deeem2031
Beiträge: 1232
Registriert: 29.08.2004 00:16
Wohnort: Vorm Computer
Kontaktdaten:

UDP.pbi für Linux

Beitrag von Deeem2031 »

Da DarkDragon zu faul war sich selber in Sachen "UDP unter Linux" zu beschäftigen, musste ich das für ihn erledigen :wink:

Im Prinzip ist es aber nur eine Konvertierung der UDP-Lib von Purefan nach Linux, wobei ich aber nicht alle Befehle übersetzt habe. Wer will kann die Übrigen hinzufügen.

Code: Alles auswählen

;UDP.pbi Version 1.2 by Deeem2031 (13.11.2005)

#SOCK_STREAM = 1
#SOCK_DGRAM = 2
#SOCK_RAW = 3
#SOCK_RDM = 4
#SOCK_SEQPACKET = 5
#SOCK_PACKET = 10

#PF_UNSPEC = 0	; Unspecified.  
#PF_LOCAL = 1 ; Local To host (pipes And file-domain).  
#PF_UNIX = #PF_LOCAL ; Old BSD name For PF_LOCAL.  
#PF_FILE = #PF_LOCAL ; Another non-standard name For PF_LOCAL.  
#PF_INET = 2 ; IP protocol family.  
#PF_AX25 = 3 ; Amateur Radio AX.25.  
#PF_IPX = 4 ; Novell Internet Protocol.  
#PF_APPLETALK = 5 ; Appletalk DDP.  
#PF_NETROM = 6 ; Amateur radio NetROM.  
#PF_BRIDGE = 7 ; Multiprotocol bridge.  
#PF_ATMPVC = 8 ; ATM PVCs.  
#PF_X25 = 9 ; Reserved For X.25 project.  
#PF_INET6 = 10 ; IP version 6.  
#PF_ROSE = 11 ; Amateur Radio X.25 PLP.  
#PF_DECnet = 12 ; Reserved For DECnet project.  
#PF_NETBEUI = 13 ; Reserved For 802.2LLC project.  
#PF_SECURITY = 14 ; Security callback pseudo AF.  
#PF_KEY = 15 ; PF_KEY key management API.  
#PF_NETLINK = 16
#PF_ROUTE = #PF_NETLINK ; Alias To emulate 4.4BSD.  
#PF_PACKET = 17 ; Packet family.  
#PF_ASH = 18 ; Ash.  
#PF_ECONET = 19 ; Acorn Econet.  
#PF_ATMSVC = 20 ; ATM SVCs.  
#PF_SNA = 22 ; Linux SNA Project 
#PF_IRDA = 23 ; IRDA sockets.  
#PF_PPPOX = 24 ; PPPoX sockets.  
#PF_WANPIPE = 25 ; Wanpipe API sockets.  
#PF_BLUETOOTH = 31 ; Bluetooth sockets.  
#PF_MAX = 32 ; For now..  

#AF_UNSPEC = #PF_UNSPEC
#AF_LOCAL = #PF_LOCAL
#AF_UNIX = #PF_UNIX
#AF_FILE = #PF_FILE
#AF_INET = #PF_INET
#AF_AX25 = #PF_AX25
#AF_IPX = #PF_IPX
#AF_APPLETALK = #PF_APPLETALK
#AF_NETROM = #PF_NETROM
#AF_BRIDGE = #PF_BRIDGE
#AF_ATMPVC = #PF_ATMPVC
#AF_X25 = #PF_X25
#AF_INET6 = #PF_INET6
#AF_ROSE = #PF_ROSE
#AF_DECnet = #PF_DECnet
#AF_NETBEUI = #PF_NETBEUI
#AF_SECURITY = #PF_SECURITY
#AF_KEY = #PF_KEY
#AF_NETLINK = #PF_NETLINK
#AF_ROUTE = #PF_ROUTE
#AF_PACKET = #PF_PACKET
#AF_ASH = #PF_ASH
#AF_ECONET = #PF_ECONET
#AF_ATMSVC = #PF_ATMSVC
#AF_SNA = #PF_SNA
#AF_IRDA = #PF_IRDA
#AF_PPPOX = #PF_PPPOX
#AF_WANPIPE = #PF_WANPIPE
#AF_BLUETOOTH = #PF_BLUETOOTH
#AF_MAX = #PF_MAX

#SOL_RAW = 255
#SOL_DECNET = 261
#SOL_X25 = 262
#SOL_PACKET = 263
#SOL_ATM = 264	; ATM layer (cell level). 
#SOL_AAL = 265	; ATM Adaption Layer (packet level). 
#SOL_IRDA = 266

#INADDR_ANY	= $00000000 ; Address To accept any incoming messages.
#INADDR_BROADCAST = $FFFFFFFF ; Address To send To all hosts.
#INADDR_NONE = $FFFFFFFF ; Address indicating an error Return.

#__SOCKADDR_COMMON_SIZE = 2 ;SizeOf(unsigned short int)

#MSG_PEEK = 2

Structure in_addr
  s_addr.l
EndStructure

Structure sockaddr
  sa_family.w ;(unsigned short int)
  sa_data.b[14]
EndStructure

Structure sockaddr_in
  sin_family.w ;(unsigned short int)
  sin_port.w;			/* Port number.
  sin_addr.in_addr ;		/* Internet address.

  sin_zero.b[SizeOf(sockaddr)-#__SOCKADDR_COMMON_SIZE-SizeOf(WORD)-SizeOf(in_addr)] ; Pad To size of `struct sockaddr'.  
EndStructure

Structure pin_addr ;pointer to in_addr
  *in_addr.in_addr
EndStructure

Structure hostent
  h_name.s
  *h_aliases.s[0]
  h_addrtype.l
  h_length.l
  StructureUnion
    *h_addrlist.pin_addr[0]
    *h_addr.pin_addr
  EndStructureUnion
EndStructure

Structure UDPConnect
  name.sockaddr_in
  socket.l
  hThread.l
  dataavailable.l
EndStructure

Structure UDPUserID
  port.w
  addr.in_addr
EndStructure

Procedure.l UDPHostByAlias(host.s)
  Protected *result.hostent
  
  *result = inet_addr_(host)
  If *result <> #INADDR_NONE
    ProcedureReturn *result
  EndIf
  *result = gethostbyname_(host)
  If *result <> 0
    ProcedureReturn *result\h_addr\in_addr\s_addr
  EndIf
  ProcedureReturn #INADDR_NONE
EndProcedure

Procedure UDPCaptureEventsThread(*ConnectID.UDPConnect)
  Protected Length
  Repeat
    Repeat
      Delay(10)
      Length = recv_(*ConnectID\socket,@r,0,#MSG_PEEK)
      Debug Length
    Until Length <> -1
    *ConnectID\dataavailable = 1
    Repeat
    Until *ConnectID\dataavailable = 0
  ForEver
EndProcedure

Procedure.l UDPInitNetwork()
  ProcedureReturn #True ;for win-compatibility
EndProcedure

Procedure.l UDPIsAvailable()
  ProcedureReturn #True ;for win-compatibility
EndProcedure

Procedure.l UDPCreateServer(port, *ConnectID.UDPConnect)
  Protected sock, name.sockaddr_in

  sock = socket_(#PF_INET, #SOCK_DGRAM, 0)
  If sock <> -1
    *ConnectID\name\sin_family = #AF_INET
    *ConnectID\name\sin_port = htons_(port)
    *ConnectID\name\sin_addr\s_addr = htonl_(#INADDR_ANY)
    If bind_(sock, *ConnectID\name, SizeOf(sockaddr_in)) = 0
      *ConnectID\socket = sock
      ProcedureReturn #True
    EndIf
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l UDPConnectServer(port,host.s,*ConnectID.UDPConnect)
  *ConnectID\name\sin_port = htons_(port)
  *ConnectID\name\sin_family = #AF_INET
  *ConnectID\name\sin_addr\s_addr = UDPHostByAlias(host)
  *ConnectID\socket = socket_(#PF_INET,#SOCK_DGRAM,0)
  If *ConnectID\socket <> -1
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l UDPStartCaptureEvents(*ConnectID.UDPConnect)
  If *ConnectID\hThread <> 0
    ProcedureReturn *ConnectID\hThread
  EndIf
  *ConnectID\hThread = CreateThread(@UDPCaptureEventsThread(),*ConnectID)
  ProcedureReturn *ConnectID\hThread
EndProcedure

Procedure UDPEndCaptureEvents(*ConnectID.UDPConnect)
  If *ConnectID\hThread <> 0
    KillThread(*ConnectID\hThread)
    *ConnectID\hThread = 0
  EndIf
EndProcedure

Procedure.l UDPReceive(*ConnectID.UDPConnect,Buffer,BufferLen)
  Protected fromlen
  If *ConnectID\hThread = 0 Or *ConnectID\dataavailable = 0
    ProcedureReturn #False
  EndIf
  
  fromlen = SizeOf(sockaddr)
  *ConnectID\dataavailable = 0
  ProcedureReturn recvfrom_(*ConnectID\socket,Buffer,BufferLen,0,*ConnectID\name,@fromlen)
EndProcedure

Procedure.l UDPWaitUntilReceive(*ConnectID.UDPConnect,Buffer,BufferLen)
  Protected fromlen
  
  fromlen = SizeOf(sockaddr)
  *ConnectID\dataavailable = 0
  ProcedureReturn recvfrom_(*ConnectID\socket,Buffer,BufferLen,0,*ConnectID\name,@fromlen)
EndProcedure

Procedure.l UDPSend(*ConnectID.UDPConnect,Buffer,BufferLen)
  sendto_(*ConnectID\socket,Buffer,BufferLen,0,*ConnectID\name,SizeOf(sockaddr))
  ProcedureReturn #True
EndProcedure

Procedure UDPSaveUserID(*UserID.UDPUserID,*ConnectID.UDPConnect)
  *UserID\port = *ConnectID\name\sin_port
  *UserID\addr\s_addr = *ConnectID\name\sin_addr\s_addr
EndProcedure

Procedure UDPLoadUserID(*UserID.UDPUserID,*ConnectID.UDPConnect)
  *ConnectID\name\sin_port = *UserID\port
  *ConnectID\name\sin_addr\s_addr = *UserID\addr\s_addr
EndProcedure

Procedure.l UDPSendToUser(*ConnectID.UDPConnect,*UserID.UDPUserID,Buffer,BufferLen)
  *ConnectID\name\sin_port = *UserID\port
  *ConnectID\name\sin_addr\s_addr = *UserID\addr\s_addr
  sendto_(*ConnectID\socket,Buffer,BufferLen,0,*ConnectID\name,SizeOf(sockaddr))
  ProcedureReturn #True
EndProcedure

Procedure.l UDPDataAvailable(*ConnectID.UDPConnect)
  ProcedureReturn *ConnectID\dataavailable
EndProcedure

Procedure.l UDPGetUserPort(*ConnectID.UDPConnect)
  ProcedureReturn htons_(*ConnectID\name\sin_port)
EndProcedure

Procedure.l UDPGetUserIP(*ConnectID.UDPConnect)
  ProcedureReturn *ConnectID\name\sin_addr\s_addr
EndProcedure

Procedure UDPCloseServer(*ConnectID.UDPConnect)
  UDPEndCaptureEvents(*ConnectID)
  close_(*ConnectID\socket)
EndProcedure

Procedure UDPCloseConnection(*ConnectID.UDPConnect)
  UDPEndCaptureEvents(*ConnectID)
  close_(*ConnectID\socket)
EndProcedure
; IDE Options = PureBasic 3.93 Beta 1 (Linux)
; CursorPosition = 201
; FirstLine = 130
; Folding = AAAA
Ich hab den Code noch nicht sehr ausführlich getestet, also bitte nicht hauen, wenns nicht funktioniert.

[Edit] Da war noch ein Debug zu viel drin.
[Edit2] UDPGetUserPort() und UDPGetUserIP() hinzugefügt.
[Edit3] UDPWaitUntilReceive() hinzugefügt.
[Edit4] Siehe 2 Posts weiter unten.
Zuletzt geändert von Deeem2031 am 13.11.2005 21:49, insgesamt 4-mal geändert.
Bild
[url=irc://irc.freenode.org/##purebasic.de]irc://irc.freenode.org/##purebasic.de[/url]
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Re: UDP.pbi für Linux

Beitrag von DarkDragon »

Deeem2031 hat geschrieben:Da DarkDragon zu faul war sich selber in Sachen "UDP unter Linux" zu beschäftigen, musste ich das für ihn erledigen :wink:
Ich bin nicht zu faul, ich bin zu blöd für sockets :lol: . Aber danke für den Code ;) .
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
MLK
Beiträge: 267
Registriert: 01.11.2004 13:17
Wohnort: Hamburg

Beitrag von MLK »

korrigiere mal "UDPDataAvaiable"
Antworten