Seite 1 von 1

UDP.pbi für Linux

Verfasst: 13.11.2005 19:10
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.

Re: UDP.pbi für Linux

Verfasst: 13.11.2005 19:23
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 ;) .

Verfasst: 13.11.2005 21:29
von MLK
korrigiere mal "UDPDataAvaiable"