BNet - Netzwerkmodul / Kompatibel mit BlitzBasic
Übersicht

Gehe zu Seite 1, 2, 3, 4, 5 Weiter
![]() |
VertexBetreff: BNet - Netzwerkmodul / Kompatibel mit BlitzBasic |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi!
Danke ersteinmal an SucoX der mir sehr geholfen hat! BMax hat ja leider keine Modul für Netzwerkzeug. Deswegen habe ich erst eine Socketlib geschrieben, die das Einbinden der SocketAPI ermöglicht. Unterstützung für TCP und UDP wobei man bis auf kleine Änderungen wie mit BlitzClassic arbeiten kann. z. B. : Code: [AUSKLAPPEN] Strict
Import "socket.bmx" Const NETLIB_MAX_CLIENTS = 10 Const NETLIB_TCP_NONE = 0 Const NETLIB_TCP_SERVER = 1 Const NETLIB_TCP_SERVCLIENT = 2 Const NETLIB_TCP_CLIENT = 3 Type TNetwork Global bInit : Byte = False Global tFDSRead : TFD_Set = Null Global tHostIPList : TBank Function InitNetwork:Int() Local tWSA:TWSAData If bInit = False Then tWSA = New TWSAData If s_WSAStartup(MAKESHORT(2, 0), tWSA) <> 0 Then Return False TTCPStream.tReadTimeout = New TTimeval TTCPStream.tAcceptTimeout = New TTimeval TTCPStream.tReadTimeout.iTV_Sec = 10 TTCPStream.tReadTimeout.iTV_USec = 0 TTCPStream.tAcceptTimeout.iTV_Sec = 0 TTCPStream.tAcceptTimeout.iTV_USec = 0 TUDPStream.tReadTimeout = New TTimeval TUDPStream.tReadTimeout.iTV_Sec = 0 TUDPStream.tReadTimeout.iTV_USec = 0 tFDSRead = New TFD_Set s_FD_ZERO(tFDSRead) tHostIPList = CreateBank(0) bInit = True Else Return False EndIf End Function Function CloseNetwork:Int() If bInit = False Then Return False bInit = False ResizeBank tHostIPList, 0 If s_WSACleanup() = SOCKET_ERROR Then Return False Else Return True EndIf End Function Function CountHostIPs:Int(sHost:String) Local pHostent:Byte Ptr, pAddress:Int Ptr Ptr, iIndex:Int If TNetwork.bInit = False Then Return 0 ResizeBank tHostIPList, 0 pHostent = w_gethostbyname(sHost.ToCString()) If Int(pHostent) = 0 Then Return 0 pAddress = Int Ptr Ptr(pHostent+12) iIndex = 1 While pAddress[iIndex] ResizeBank tHostIPList, iIndex*4 PokeInt tHostIPList, (iIndex-1)*4, Var pAddress[iIndex] iIndex = iIndex+1 Wend Return iIndex-1 End Function Function HostIP:Int(iIndex:Int) Local iCount:Int If TNetwork.bInit = False Then Return 0 iCount = BankSize(tHostIPList)/4 If iIndex = 0 Or iIndex > iCount Then Return 0 Return s_ntohl(PeekInt(tHostIPList, (iIndex-1)*4)) End Function Function DottedIP:String(iIP:Int) Return s_inet_ntoa(s_htonl(iIP)) End Function End Type Function InitNetwork:Int() Return TNetwork.InitNetwork() End Function Function CloseNetwork:Int() Return TNetwork.CloseNetwork() End Function Function CountHostIPs:Int(sHost:String) Return TNetwork.CountHostIPs(sHost) End Function Function HostIP:Int(iIndex:Int) Return TNetwork.HostIP(iIndex) End Function Function DottedIP:String(iIP:Int) Return TNetwork.DottedIP(iIP) End Function Type TTCPStream Extends TStream Global tReadTimeout : TTimeval = Null Global tAcceptTimeout : TTimeval = Null Field bType : Byte = NETLIB_TCP_NONE Field tParent : TTCPStream = Null Field iSocket : Int = INVALID_SOCKET Field tAddress : TSockAddr = Null Field tRemoteAddr : TSockAddr = Null Field iEOF : Int = 0 Function TCPStreamIP:Int(tTCP:TTCPStream) If tTCP = Null Then Return 0 If tTCP.tAddress = Null Then Return 0 Return s_ntohl(tTCP.tAddress.iSinAddr) End Function Function TCPStreamPort:Short(tTCP:TTCPStream) If tTCP = Null Then Return 0 If tTCP.tAddress = Null Then Return 0 Return s_ntohs(tTCP.tAddress.shSinPort) End Function Function TCPTimeouts(iReadMillisecs:Int, iAcceptMillisecs:Int) If TNetwork.bInit = False Then Return TTCPStream.tReadTimeout.iTV_Sec = Int(iReadMillisecs / 1000) TTCPStream.tReadTimeout.iTV_USec = iReadMillisecs Mod 1000 TTCPStream.tAcceptTimeout.iTV_Sec = Int(iAcceptMillisecs / 1000) TTCPStream.tAcceptTimeout.iTV_USec = iAcceptMillisecs Mod 1000 End Function Method Eof() Return iEOF End Method Method Close() s_shutdown(iSocket, 2) s_closesocket(iSocket) iSocket = INVALID_SOCKET iEOF = 1 End Method Method Read(pBuffer:Byte Ptr, iCount:Int) Local iResult:Int Print "Lese "+iCount+" Bytes" Print "Socket: "+iSocket If iSocket = INVALID_SOCKET Then iEOF = -1 Return 0 EndIf Select bType Case NETLIB_TCP_SERVER iEOF = -1 Return 0 Case NETLIB_TCP_SERVCLIENT If tParent = Null Or iSocket = INVALID_SOCKET Then iEOF = -1 Return 0 EndIf s_FD_ZERO(TNetwork.tFDSRead) s_FD_SET(tParent.iSocket, TNetwork.tFDSRead) If s_select(0, TNetwork.tFDSRead, Null, Null, tReadTimeout) = SOCKET_ERROR Then iEOF = -1 Return 0 EndIf If Not s_FD_ISSET(iSocket, TNetwork.tFDSRead) Then Return 0 iResult = s_recv(iSocket, pBuffer, iCount, 0) Print "Result: "+iResult If iResult = 0 Then iEOF = 1 Return 0 ElseIf iResult = SOCKET_ERROR Then iEOF = -1 Return 0 Else iEOF = 0 Return iResult EndIf Case NETLIB_TCP_CLIENT If iSocket = INVALID_SOCKET Then iEOF = -1 Return 0 EndIf s_FD_ZERO(TNetwork.tFDSRead) s_FD_SET(iSocket, TNetwork.tFDSRead) If s_select(iSocket, TNetwork.tFDSRead, Null, Null, tReadTimeout) = SOCKET_ERROR Then iEOF = -1 Return 0 EndIf If Not s_FD_ISSET(iSocket, TNetwork.tFDSRead) Then Return 0 iResult = s_recv(iSocket, pBuffer, iCount, 0) If iResult = SOCKET_ERROR Or iResult = -1 Then iEOF = -1 Return 0 ElseIf iResult = 0 Then iEOF = 1 Return 0 Else iEOF = 0 Return iResult EndIf End Select End Method Method Write(pBuffer:Byte Ptr, iCount:Int) Local iResult:Int Print "Schreibe "+iCount+" Bytes" Print "Socket: "+iSocket If iSocket = INVALID_SOCKET Then Return 0 Select bType Case NETLIB_TCP_SERVER Return 0 Case NETLIB_TCP_SERVCLIENT iResult = s_send(iSocket, pBuffer, iCount, 0) If iResult = SOCKET_ERROR Then iEOF = -1 Return 0 ElseIf iResult = 0 Then iEOF = 1 Return 0 Else iEOF = 0 Return iResult EndIf Case NETLIB_TCP_CLIENT If tRemoteAddr = Null Then iResult = s_send(iSocket, pBuffer, iCount, 0) Else iResult = s_sendto(iSocket, pBuffer, iCount, 0, tRemoteAddr, 16) EndIf Print "Result: "+iResult Print "Fehler: "+s_WSAGetLastError() If iResult = SOCKET_ERROR Then iEOF = -1 Return 0 ElseIf iResult = 0 Then iEOF = 1 Return 0 Else iEOF = 0 Return iResult EndIf End Select End Method End Type Function TCPStreamIP:Int(tTCP:TTCPStream) Return TTCPStream.TCPStreamIP(tTCP) End Function Function TCPStreamPort:Short(tTCP:TTCPStream) Return TTCPStream.TCPStreamPort(tTCP) End Function Function TCPTimeouts(iReadMillisecs:Int, iAcceptMillisecs:Int) TTCPStream.TCPTimeouts(iReadMillisecs, iAcceptMillisecs) End Function Type TTCPServer Extends TTCPStream Function CreateTCPServer:TTCPServer(shPort:Short) Local tServer:TTCPServer If TNetwork.bInit = False Then Return Null tServer = New TTCPServer tServer.bType = NETLIB_TCP_SERVER tServer.iSocket = s_socket(AF_INET, SOCK_STREAM, 0) If tServer.iSocket = INVALID_SOCKET Then Return Null tServer.tAddress = New TSockAddr tServer.tAddress.shSinFamily = AF_INET tServer.tAddress.shSinPort = s_htons(shPort) tServer.tAddress.iSinAddr = INADDR_ANY If s_bind(tServer.iSocket, tServer.tAddress, 16) = SOCKET_ERROR Then s_closesocket(tServer.iSocket) Return Null EndIf If s_listen(tServer.iSocket, NETLIB_MAX_CLIENTS) = SOCKET_ERROR Then s_shutdown(tServer.iSocket, 2) s_closesocket(tServer.iSocket) Return Null EndIf Return tServer End Function Function AcceptTCPStream:TTCPStream(tServer:TTCPServer) Local tServClient:TTCPStream, iSocket:Int, tAddress:TSockAddr, iRemoteLen:Int If tServer = Null Then Return Null s_FD_ZERO(TNetwork.tFDSRead) s_FD_SET(tServer.iSocket, TNetwork.tFDSRead) If s_select(0, TNetwork.tFDSRead, Null, Null, TTCPStream.tAcceptTimeout) = SOCKET_ERROR Then Return Null EndIf If s_FD_ISSET(tServer.iSocket, TNetwork.tFDSRead) Then tAddress = New TSockAddr iRemoteLen = 16 iSocket = s_accept(tServer.iSocket, tAddress, Varptr iRemoteLen) If iSocket = SOCKET_ERROR Then Return Null Else tServClient = New TTCPStream tServClient.bType = NETLIB_TCP_SERVCLIENT tServClient.tParent = tServer tServClient.iSocket = iSocket tServClient.tAddress = tAddress Return tServClient EndIf EndIf End Function Function CloseTCPServer(tServer:TTCPServer) If tServer = Null Then Return tServer.Close() End Function End Type Function CreateTCPServer:TTCPServer(shPort:Short) Return TTCPServer.CreateTCPServer(shPort) End Function Function AcceptTCPStream:TTCPStream(tServer:TTCPServer) Return TTCPServer.AcceptTCPStream(tServer) End Function Function CloseTCPServer(tServer:TTCPServer) TTCPServer.CloseTCPServer(tServer) End Function Type TTCPClient Extends TTCPStream Function OpenTCPStream:TTCPClient(sURL:String, shPort:Short, shLocalPort:Short = 0) Local tClient:TTCPClient If TNetwork.bInit = False Then Return Null tClient = New TTCPClient tClient.bType = NETLIB_TCP_CLIENT tClient.iSocket = s_socket(AF_INET, SOCK_STREAM, 0) If tClient.iSocket = INVALID_SOCKET Then Return Null If shLocalPort = 0 tClient.tAddress = New TSockAddr tClient.tAddress.shSinFamily = AF_INET tClient.tAddress.shSinPort = s_htons(shPort) tClient.tAddress.iSinAddr = s_gethostbyname(sURL) tClient.tRemoteAddr = Null Else tClient.tAddress = New TSockAddr tClient.tAddress.shSinFamily = AF_INET tClient.tAddress.shSinPort = s_htons(shLocalPort) tClient.tAddress.iSinAddr = s_gethostbyname(sURL) tClient.tRemoteAddr = New TSockAddr tClient.tRemoteAddr.shSinFamily = tClient.tAddress.shSinFamily tClient.tRemoteAddr.shSinPort = s_htons(shPort) tClient.tRemoteAddr.iSinAddr = tClient.tAddress.iSinAddr EndIf If tClient.tAddress.iSinAddr = SOCKET_ERROR Then s_shutdown(tClient.iSocket, 2) s_closesocket(tClient.iSocket) Return Null EndIf If s_connect(tClient.iSocket, tClient.tAddress, 16) = SOCKET_ERROR Then s_shutdown(tClient.iSocket, 2) s_closesocket(tClient.iSocket) Return Null EndIf Return tClient End Function Function CloseTCPStream(tClient:TTCPClient) If tClient = Null Then Return tClient.Close() End Function End Type Function OpenTCPStream:TTCPClient(sURL:String, shPort:Short, shLocalPort:Short = 0) Return TTCPClient.OpenTCPStream:TTCPClient(sURL, shPort, shLocalPort) End Function Function CloseTCPStream(tClient:TTCPClient) TTCPClient.CloseTCPStream(tClient) End Function Type TUDPStream Extends TStream Global tReadTimeout:TTimeval = Null Field iSocket : Int = INVALID_SOCKET Field tAddress : TSockAddr = Null Field tRemoteAddr : TSockAddr = Null Field tReadBuffer : TBank = Null Field tWriteBuffer : TBank = Null Field iEOF : Int Function UDPTimeouts(iReadMillisecs:Int) If TNetwork.bInit = False Then Return tReadTimeout.iTV_Sec = Int(iReadMillisecs / 1000) tReadTimeout.iTV_USec = iReadMillisecs Mod 1000 End Function Function CreateUDPStream:TUDPStream(shPort:Short = 0) Local tUDP:TUDPStream, iNameLen:Int If TNetwork.bInit = False Then Return Null tUDP = New TUDPStream tUDP.iSocket = s_socket(AF_INET, SOCK_DGRAM, 0) If tUDP.iSocket = INVALID_SOCKET Then Return Null tUDP.tAddress = New TSockAddr tUDP.tAddress.shSinFamily = AF_INET tUDP.tAddress.shSinPort = s_htons(shPort) tUDP.tAddress.iSinAddr = INADDR_ANY If s_bind(tUDP.iSocket, tUDP.tAddress, 16) = SOCKET_ERROR Then s_closesocket(tUDP.iSocket) Return Null EndIf iNameLen = 16 If s_getsockname(tUDP.iSocket, tUDP.tAddress, Varptr iNameLen) = SOCKET_ERROR Then s_closesocket(tUDP.iSocket) Return Null EndIf tUDP.tRemoteAddr = New TSockAddr tUDP.tRemoteAddr.shSinFamily = tUDP.tAddress.shSinFamily tUDP.tRemoteAddr.shSinPort = tUDP.tAddress.shSinPort tUDP.tRemoteAddr.iSinAddr = tUDP.tAddress.iSinAddr tUDP.tReadBuffer = CreateBank(0) tUDP.tWriteBuffer = CreateBank(0) tUDP.iEOF = 0 Return tUDP End Function Function CloseUDPStream(tUDP:TUDPStream) s_shutdown(tUDP.iSocket, 2) s_closesocket(tUDP.iSocket) tUDP.iSocket = INVALID_SOCKET tUDP.iEOF = 1 End Function Function RecvUDPMsg:Int(tUDP:TUDPStream) Local iResult:Int, tTempBuffer:TBank, iRemoteLen:Int, iSize:Int If tUDP = Null Or tUDP.iSocket = INVALID_SOCKET Then Return s_FD_ZERO(TNetwork.tFDSRead) s_FD_SET(tUDP.iSocket, TNetwork.tFDSRead) If s_select(0, TNetwork.tFDSRead, Null, Null, tReadTimeout) = SOCKET_ERROR Then Return 0 If Not s_FD_ISSET(tUDP.iSocket, TNetwork.tFDSRead) Then Return 0 tTempBuffer = CreateBank(1024) iRemoteLen = 16 iResult = s_recvfrom(tUDP.iSocket, BankBuf(tTempBuffer), 1024, 0, tUDP.tRemoteAddr, Varptr iRemoteLen) If iResult = 0 Or iResult = SOCKET_ERROR Then If BankSize(tUDP.tReadBuffer) = 0 Then tUDP.iEOF = 1 Else tUDP.iEOF = 0 EndIf Return 0 Else iSize = BankSize(tUDP.tReadBuffer) ResizeBank tUDP.tReadBuffer, iSize+iResult MemCopy BankBuf(tUDP.tReadBuffer)+iSize, BankBuf(tTempBuffer), iResult tUDP.iEOF = 0 Return s_ntohl(tUDP.tRemoteAddr.iSinAddr) EndIf End Function Function SendUDPMsg(tUDP:TUDPStream, iIP:Int, shPort:Short = 0) Local iSize:Int, iResult:Int, shOldPort:Short, tTempBuffer:TBank If tUDP = Null Or tUDP.iSocket = INVALID_SOCKET Then Return iSize = BankSize(tUDP.tWriteBuffer) If iSize = 0 Then Return shOldPort = tUDP.tRemoteAddr.shSinPort If shPort <> 0 Then shOldPort = tUDP.tRemoteAddr.shSinPort tUDP.tRemoteAddr.shSinPort = s_htons(shPort) EndIf tUDP.tRemoteAddr.iSinAddr = s_htonl(iIP) iResult = s_sendto(tUDP.iSocket, BankBuf(tUDP.tWriteBuffer), iSize, 0, tUDP.tRemoteAddr, 16) tUDP.tRemoteAddr.shSinPort = shOldPort If iResult = 0 Or iResult = SOCKET_ERROR Then Return ElseIf iResult < iSize Then tTempBuffer = CreateBank(iSize-iResult) MemCopy BankBuf(tTempBuffer), BankBuf(tUDP.tWriteBuffer)+iResult, iSize-iResult ResizeBank tUDP.tWriteBuffer, iSize-iResult MemCopy BankBuf(tUDP.tWriteBuffer), BankBuf(tTempBuffer), iSize-iResult Return Else ResizeBank tUDP.tWriteBuffer, 0 Return EndIf End Function Function UDPMsgIP:Int(tUDP:TUDPStream) If tUDP = Null Then Return 0 If tUDP.tRemoteAddr = Null Then Return 0 Return s_ntohl(tUDP.tRemoteAddr.iSinAddr) End Function Function UDPMsgPort:Short(tUDP:TUDPStream) If tUDP = Null Then Return 0 If tUDP.tRemoteAddr = Null Then Return 0 Return s_ntohs(tUDP.tRemoteAddr.shSinPort) End Function Function UDPStreamIP:Int(tUDP:TUDPStream) If tUDP = Null Then Return 0 Return s_ntohl(INADDR_ANY) End Function Function UDPStreamPort:Short(tUDP:TUDPStream) If tUDP = Null Then Return 0 If tUDP.tAddress = Null Then Return 0 Return s_ntohs(tUDP.tAddress.shSinPort) End Function Method Eof() Return iEOF End Method Method Size() Return BankSize(tReadBuffer) End Method Method Flush() ResizeBank tReadBuffer, 0 ResizeBank tWriteBuffer, 0 iEOF = 1 End Method Method Close() s_shutdown(iSocket, 2) s_closesocket(iSocket) iSocket = INVALID_SOCKET iEOF = 1 End Method Method Read(pBuffer:Byte Ptr, iCount:Int) Local iSize:Int, tTempBuffer:TBank If iSocket = INVALID_SOCKET Then Return 0 iSize = BankSize(tReadBuffer) If iSize = 0 Or iSize < iCount Then Return 0 MemCopy pBuffer, BankBuf(tReadBuffer), iCount If iSize = iCount Then ResizeBank tReadBuffer, 0 iEOF = 1 Else tTempBuffer = CreateBank(iSize-iCount) MemCopy BankBuf(tTempBuffer), BankBuf(tReadBuffer)+iCount, iSize-iCount ResizeBank tReadBuffer, iSize-iCount MemCopy BankBuf(tReadBuffer), BankBuf(tTempBuffer), iSize-iCount iEOF = 0 EndIf Return iCount End Method Method Write(pBuffer:Byte Ptr, iCount:Int) Local iSize:Int If iSocket = INVALID_SOCKET Then Return 0 iSize = BankSize(tWriteBuffer) ResizeBank tWriteBuffer, iSize+iCount MemCopy BankBuf(tWriteBuffer)+iSize, pBuffer, iCount Return iCount End Method End Type Function UDPTimeouts(iReadMillisecs:Int) TUDPStream.UDPTimeouts(iReadMillisecs) End Function Function CreateUDPStream:TUDPStream(shPort:Short = 0) Return TUDPStream.CreateUDPStream(shPort) End Function Function CloseUDPStream(tUDP:TUDPStream) TUDPStream.CloseUDPStream(tUDP) End Function Function RecvUDPMsg:Int(tUDP:TUDPStream) Return TUDPStream.RecvUDPMsg(tUDP) End Function Function SendUDPMsg(tUDP:TUDPStream, iIP:Int, shPort:Short = 0) TUDPStream.SendUDPMsg(tUDP, iIP, shPort) End Function Function UDPMsgIP:Int(tUDP:TUDPStream) Return TUDPStream.UDPMsgIP(tUDP) End Function Function UDPMsgPort:Short(tUDP:TUDPStream) Return TUDPStream.UDPMsgPort(tUDP) End Function Function UDPStreamIP:Int(tUDP:TUDPStream) Return TUDPStream.UDPStreamIP(tUDP) End Function Function UDPStreamPort:Short(tUDP:TUDPStream) Return TUDPStream.UDPStreamPort(tUDP) End Function Das ganze ist OpenSource und steht unter keinen Lizensbedingungen. mfg olli |
||
vertex.dreamfall.at | GitHub |
- Zuletzt bearbeitet von Vertex am Do, Jul 14, 2005 18:51, insgesamt 5-mal bearbeitet
morszeck |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hoffe dies wird bald in der offiziellen Bmax-Release einfliessen. Ein paar andere haben es auch schon geschaft.
Super Arbeit!!! |
||
![]() |
Suco-XBetreff: ......... |
![]() Antworten mit Zitat ![]() |
---|---|---|
Jep. Spitze das Teil. Werde ich heute mal kräftig austesten.
Mfg Suco |
||
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB |
ChristianH |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Respekt, gute Arbeit.
Wenn es auf Linux und MacOS funktioniert wird man es bestimmt in den offiziellen Release tun. |
||
![]() |
Suco-XBetreff: ......... |
![]() Antworten mit Zitat ![]() |
---|---|---|
Habe mal den ersten Test gemacht .Irgendwas stimmt da bei mir nicht.
Server : Code: [AUSKLAPPEN] 'Server Import "vertexnetwork.bmx" Const StreamPort:int = 4662 Global ChatString:string = "" Graphics 640,480,0 InitNetwork() Local UdpStream:int = createUdpStream(StreamPort) If UdpStream = 0 Notify("Stream exestiert nicht") End EndIf Repeat Cls Delay(50) If SmallInput() = 1 ChatString = "" EndIf If recvudpmsg(UdpStream) Print ReadLine(UdpStream) EndIf DrawText ChatString,10,10 DrawText CurrentIp,10,50 Flip FlushMem() Until KeyHit(KEY_ESCAPE) Function SmallInput() If KeyHit(KEY_RETURN) Return True EndIf Local Ascii:int = getchar() If Ascii ChatString:+chr(Ascii) EndIf Return False End Function Und er Client : Code: [AUSKLAPPEN] 'Client Import "vertexnetwork.bmx" Const StreamPort:int = 4662 Graphics 800,600,0 InitNetwork() Global ChatString:string = "" Local UdpStream:int = createUdpStream() Local CurrentIp:int = 0 Local IP:int = Int_IP("127.0.0.1") If UdpStream = 0 Notify("Stream exestiert nicht") End EndIf Repeat Cls Delay(40) If SmallInput() = 1 WriteLine(udpstream,ChatString) SendUdpMsg(UdpStream,IP,StreamPort) ChatString = "" EndIf DrawText ChatString,10,10 Flip FlushMem() Until KeyHit(KEY_ESCAPE) Function SmallInput() If KeyHit(KEY_RETURN) Return True EndIf Local Ascii:int = getchar() If Ascii ChatString:+chr(Ascii) EndIf Return False End Function Function INT_IP(IP:string) Local a1=INT(LEFT(IP,INSTR(IP,".")-1));IP=RIGHT(IP,LEN(IP)-INSTR(IP,".")) Local a2=INT(LEFT(IP,INSTR(IP,".")-1));IP=RIGHT(IP,LEN(IP)-INSTR(IP,".")) Local a3=INT(LEFT(IP,INSTR(IP,".")-1));IP=RIGHT(IP,LEN(IP)-INSTR(IP,".")) Local a4=INT(IP$) RETURN (a1 SHL 24) + (a2 SHL 16) + (a3 SHL 8 ) +a4 END FUNCTION Das erste mal Sendet der Client den richtigen Satz. Danach sendet er aber immer den gleichen Satz an den Server. Oder der Server nimmt immer den ersten Satz. Ka. Kann sich ja vllt mal einer anschauen. [EDIT1] Mit dem alten BB geht das ganze Reibungslos. [/EDIT1] Mfg Suco |
||
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi!
Ersteinmal danke für die gute Resonanz! Fürs erste INT_IP kann man sich ersparen, in dem man s_htonl(s_inet_addr("127.0.0.1")) einsetzt. Bei URLs geht auch s_htonl(s_gethostbyname("127.0.0.1")). Suco: Ja, der liest wirklich den Buffer erneut aus. Mein Gedanke war folgender: Ich habe eine Bank in dem alle eingehenden Daten abgespeichert werden. Kommt eine Nachricht beim Aufruf von RecvUDPMsg, dann wird diese Bank um die Anzahl der empfangenen Bytes erweitert. Die empfangenen Bytes werden dann in diese freie Stelle der Bank gespeichert. Kommt jetzt z. B. ReadLine soll er die alten Daten auslesen lassen. Also liest er praktisch aus dem Amfang der Bank. Ist er damit fertig, wie der Teil, der noch nciht ausgelesen wurde, zwischen gespeichert, die Bank um die gelesenen Bytes verkleinert, und das Zwischengespeicherte wieder zurückkopiert. Scheint aber nicht zu gehen ![]() Ich muss sagen, das mir das ganze nicht ganz gefällt, wie es BlitzClassic handhabt. Das ist unnötige Performenceverschwendung. Ich überlege mir, vllt. die Befehle umzugestalten. So das RecvUDPMsg z. B. in einem angegebenen Puffer die Daten abspeichert, und die Anzahl an gelesenen Bytes zurückgibt. Das selbe für SendUDPMsg. Aber mal schauen.... Edit: Ich habe anscheinend das falsche debugt. Es liegt wohl eher an SendUDPMsg statts an RecvUDPMsg ![]() Edit: Jo lag an SendUDPMsg, habe den tReadBuffer auf 0 verkleinert, statts den tWriteBuffer und irgendwo noch was geändert(den neuen Code findet ihr im ersten Thread) Hier meine Testcodes: Server: Code: [AUSKLAPPEN] Strict
Import "NetLib.bmx" Local UDP:TUDPStream Local Message:String Local IP:Int InitNetwork() UDPTimeouts 1000 UDP = CreateUDPStream(1234) While True IP = RecvUDPMsg(UDP) If IP <> 0 Then Message = ReadLine(UDP) Print "IP: "+DottedIP(UDPMsgIP(UDP)) Print "Port: "+UDPMsgPort(UDP) Print "Message: "+Message WriteLine UDP, "I have received: "+Message SendUDPMsg UDP, IP, UDPMsgPort(UDP) EndIf Wend CloseUDPStream UDP Client: Code: [AUSKLAPPEN] Strict
Import "NetLib.bmx" Local UDP:TUDPStream Local Message:String Local IP:Int InitNetwork() UDPTimeouts 1000 UDP = CreateUDPStream() IP = s_htonl(s_gethostbyname("127.0.0.1")) While True Message = Input("Text: ") If Message = "quit" Then Exit WriteLine UDP, Message SendUDPMsg UDP, IP, 1234 If RecvUDPMsg(UDP) <> 0 Then Print "Message: "+ReadLine(UDP) EndIf Wend CloseUDPStream UDP |
||
vertex.dreamfall.at | GitHub |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Neue Version. RecvUDPMsg / SendUDPMsg von grundauf neu geschrieben. Schmerzlichen Dank hier an SucoX!
Suco hat übrigens mal ein gutes Bsp. geschrieben das jetzt geht. Neue Lib habe ich oben editiert! http://www.sucox.art-fx.org/Bl...ode_id=599 mfg olli |
||
vertex.dreamfall.at | GitHub |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Habe nun CountHostIPs und HostIP eingebaut. Beispiel:
Code: [AUSKLAPPEN] InitNetwork()
iCount = CountHostIPs("google.de") If iCount = 0 Then Print "Fehler: Konnte Host nicht finden" Delay 2000 ; End EndIf Print "google.de hat folgende IPs:" For iIndex = 1 To iCount Print DottedIP(HostIP(iIndex)) Next CloseNetwork() (muss man mal mit .at, .de, .com in Laufe der Zeit probieren, da google irgendwie die 2 IPs am Tag auf versch. Topleveldomains verstreut) HostIP gibt 0 zurück, wenn der Index nicht gefunden wurde. So noch ein wenig bugfixing, und dann das ganze als Modul verpacken... mfg olli |
||
vertex.dreamfall.at | GitHub |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Das Ganze steht nun als Modul zur Verfügung:
http://vertex.art-fx.org/bnet.zip API habe ich nun mit eingebunden, MemCopy2 herausgeknallt(dank Core 1.03) und ein paar bugs gefixet. Ich sehe zu, das ich noch ein ReadAvail mit einbaue. Dieses würde dann Auskunft geben, ob man Daten zum Auslesen vorliegen hat, kann aber nicht die Anzahl an Bytes zurückgeben. Linuxversion wird auch bald kommen. hamZta hat mir schonmal die Header-Dateien geschickt, wo ich schauen kann, welche Änderungen vorgenommen werden müssen(hauptsächlich nur an den FD_Sets) mfg olli |
||
vertex.dreamfall.at | GitHub |
![]() |
stfighter01 |
![]() Antworten mit Zitat ![]() |
---|---|---|
habs noch nicht getestet, aber wenn es tut was du sagst : RESPEKT | ||
Denken hilft! |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
stfighter01: es gibt bis her keine Fehler die ich gefunden habe ![]() http://vertex.art-fx.org/bnet.zip <- neuste Version mit ReadAvail! Jetzt sind alle Netzwerkbefehle übersetzt. mfg olli |
||
vertex.dreamfall.at | GitHub |
![]() |
regaa |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wie immer kann ich über deine Arbeit nur staunen. Great Job. | ||
UltraMixer Professional 3 - Download
QB,HTML,CSS,JS,PHP,SQL,>>B2D,B3D,BP,BlitzMax,C,C++,Java,C#,VB6 , C#, VB.Net |
![]() |
bruZard |
![]() Antworten mit Zitat ![]() |
---|---|---|
*AAAH* vertex ... ich bin eine Woche nicht da, Du baust alles was mir für das neue i.Score Release gefehlt hat, GetChar() ist endlich da, ne neue BMax Version, neue BMax IDE und sowenig Zeit das alles zu testen.
Ich nutze Deine Mod für i.Score und setze Dir ein Denkmal in den Credits ![]() |
||
PIV 2,4GHz - 1GB DDR 333 - ATI Radeon9600 - WinXP - DX9.0c - BMax 1.14 - B3D 1.91 - 1280x1024x32
User posted image |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Bin dabei alles nach Linux zu portieren. Ich habe mir mal die Mühe gemacht, und mein vorhaben dokumentiert!
Als meine Netlib - jetzt genannt bnet released wurde, habe ich mir darum gedanken gemacht, wie ich das ganze nach Linux und auch event. nach Max portieren könnte. Letzendlich besitzt Linux wie auch Windows Berkeley Socket Struktur. Was mache ich? Gut es gibt ein nettes Tutorial http://www.pc adviser.de/socket_programmierung.html wo alles für Unix geschrieben wurde. Da steht auch drin, das ich statts closesocket z. B. close nur werwenden muss (abgesehen davon, das man natürlich WSAStartup/Cleanup nciht benötigt). Ein Blick auf http://www.c-worker.ch/tuts/select.html verrät mir, das fd_set Struktur unter Linux eine komische Bitmaske sein soll. Ich schenke den Ganzen erstmal keine detailierte Aufmerksamkeit und mache mir eine Liste mit allen Änderungen die ich durchführen muss:
- FD_CLR -> ? - WSAFDIsSet -> ? - FD_SET -> ? - FD_ZERO -> ? - select -> ? - closesocket -> close - WSACleanup -> weglassen Ein Tag später bemerke ich zusätzlich, das es kein ioctlsocket gibt unter Linux. also:
Jetzt heißt es googlen! Schlau wie ich bin, suche ich dann gleich mal nach "Linux ioctlsocket" Wie gewünscht ist z. B. gleich die erste Seite ein voller Treffer. http://www.irietools.com/iriep...ef375.html WinSock hat zwar nix mit Linux zu tun, aber google hat immer recht! Ok weitersuchen! Schlampig wie ich bin, übersehe ich da http://safariexamples.informit...k/socket.c Nächster Tag, voll motiviert entdecke ich also den C Code, lade ihn in DevC++ und bemühe die Suchfunktion noch ioctlsocket. Und siehe da: Code: [AUSKLAPPEN] #if defined (WIN32)
if (ioctlsocket(f, FIONBIO, &on) < 0) #endif #ifdef LINUX if (ioctl(f, FIONBIO, &on) < 0) #endif Also Liste ändern:
- FD_CLR -> ? - WSAFDIsSet -> ? - FD_SET -> ? - FD_ZERO -> ? - select -> ? - closesocket -> close - WSACleanup -> weglassen - ioctsocket -> ioctl Diese ? machen mir aber noch gewaltig sorgen, zumal ich noch in Erinnerung "Bitmasken" habe. Da ich Desktop-Linux nur scheiße finde(GNOME ist ja eine einzige Zumutung), habe ich mal Laut im Blitz-Chat nach Headerdatein gefragt. Hamzta(soll das auf Hoppersprache "Hamster" heißen???) war so nett, und schickt mir ein paar Headerdateien die ich im laufe von Google Misserfolgen noch kannte. Also alles in DevC++ laden, und mal schauen was passiert... Code: [AUSKLAPPEN] /* It also defines `fd_set' and the FD_* macros for `select'. */
# include <sys/select.h> OK, ist schonmal ein Stückchen Code, es kann nur noch besser werden. > GOOOOOOOGLEN!!!!!!! Wow, diesmal versagen meine Augen nicht und ich finde direkt auf Anhieb: http://www.die.net/doc/linux/include/sys/select.h Was muss ich jedoch mal wieder darin baugapfeln? Code: [AUSKLAPPEN] /* Access macros for `fd_set'. */
#define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp) #define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp) #define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp) #define FD_ZERO(fdsetp) __FD_ZERO (fdsetp) Jaaaaaa! Makros, das sind die Dinger die alle Headerdateien von Grundauf zu Nichte machen. Aus diesem Grund mag ich keine eingefleischten C/C++ Programmierer! Naja OK, vllt. sind die Makros mal ganz Einfach gebaut... Gleich mal __FD_ZERO googlen... Da findet man irgendwie was an Linuxscipt erinnert. Ein riesen Kauderwelch(ja ich komme aus dem Osten!) und irgend ein komischer Assemblercode der Linuxstandard total unverständlich ist(von wegen OpenSource, die wollen garnicht, das man den Sourcecode versteht!) Aber ich lasse mir für gewöhnlich nicht von Linuxtypen und garnicht von Google ans Bein pissen. Ich schau nämlich auch wenn es ein muss, auf die 2. Suchseite!(wie gesagt, wenn es sein muss!). Und siehe da, http://pc1.peanuts.gr.jp/~kei/...ix_types.h DevC++!!!!!! Hier sind also diese kleinen fiesen makros definiert(#define -> definiert, welch ein schlechtes Wortspiel!) Code: [AUSKLAPPEN] #define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) #define __FD_ISSET(d, set) (((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) != 0) #define __FD_ZERO(set) \ ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set))) Hmmm aber wenn ich ein wenig nach oben schaue, und wieder nach unten, gibt es ja sogar 2 Versionen von den ganzen Makros. Code: [AUSKLAPPEN] # ifndef __GNUC__
Ist der Überltäter. Nach der Else-Direktive kommt mal wieder ein wenig C Code. Was rede ich da, es ist C++. Aber es gibt mal wieder ein Problem: Code: [AUSKLAPPEN] static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
{ unsigned long _tmp = fd / __NFDBITS; unsigned long _rem = fd % __NFDBITS; fdsetp->fds_bits[_tmp] |= (1UL<<_rem); } What the hell ist 1UL<<_rem?(Ich sag doch, Linux ist nie wirklich OpenSource gewesen!) Da BMax eh kein C++ Code einbinden kann(nur C), nehme ich mal lieber doch die Makros oben vor... Jetzt komme ich auch mal zu den eigentlichen Problem. Wie sieht fd_set Struktur unter Linux aus???? Wie der Zufall es will, habe ich hier select.h auf der Platte! Da sehen meine bezaubernden auch auch gleich Code: [AUSKLAPPEN] /* fd_set for select and pselect. */
typedef struct { /* XPG4.2 requires this member name. Otherwise avoid the name from the global namespace. */ #ifdef __USE_XOPEN __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS]; # define __FDS_BITS(set) ((set)->fds_bits) #else __fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS]; # define __FDS_BITS(set) ((set)->__fds_bits) #endif } fd_set; Mir wird auch gleich wieder kotzschlecht von den ganzen Makros(für was bemühe ich mich eigentlich immer sauberstrukturierten Code zu schreiben?) Ich lese mal die Kommentare(kann ja nicht schaden), und lösche sie auch gleich wieder. "XPG4.2" habe ich noch nie gehört(da ich kein Desktop Linux mag, werde ich es auch nie erfahren!). Zudem brauche ich keine schrecklichen ifdefs! Da XPG42.2 mir nicht gefällt, nehme ich mal den Else-Fall. Code: [AUSKLAPPEN] typedef struct
{ __fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS]; } fd_set; Hach! Sieht doch gleich viel sauberer aus! __fd_mask, hmm Makro! -> Suchen! Was muss ran? Genau, die Suchfunktion! Code: [AUSKLAPPEN] typedef long int __fd_mask;
Ja mal eine Typdefinition, long int da bei fd_set zu schreiben wäre ja auch voll un-pro! Code: [AUSKLAPPEN] typedef struct
{ long int __fds_bits[__FD_SETSIZE / __NFDBITS]; } fd_set; __FD_SETSIZE und __NFDBITS stehen da noch ganz alleine herum. Und auch diese sind mal glücklicherweise in select.h gleich definiert worde (auf das scheiß Wortspiel weise ich mal nicht hin ![]() Code: [AUSKLAPPEN] #define __NFDBITS (8 * sizeof (__fd_mask))
Zu früh gefreut!(Wäre ja auch schlimm, wenn ich mal Glück haben sollte). Es fehlt doch noch __FD_SETSIZE. Natürlich fehlt mir mal irgendeine Headerdatei, wo __FD_SETSIZE definiert worden ist. Google!!! Naja nach sehr laaangen Suchen bin ich dan igrnedwie auf http://www.ussg.iu.edu/hyperma.../0060.html gestoßen. (Über das Makrowirwar reg ich mich jetzt nichtmehr auf ?OK) Code: [AUSKLAPPEN] #undef __FD_SETSIZE
-#define __FD_SETSIZE 4096 +#define __FD_SETSIZE 1024 Hmm was heißt bitteschön +#define und -#define??? Frei nach Schnauze nehme ich mal 1024... Code: [AUSKLAPPEN] typedef struct
{ __fd_mask __fds_bits[1024 / 8 * sizeof (__fd_mask)]; } fd_set; Ergo: Code: [AUSKLAPPEN] typedef struct
{ __fd_mask __fds_bits[1024 / 8 * 4]; } fd_set; Wow! Das lässt sich doch mal auf BMax übertragen! Code: [AUSKLAPPEN] Type TFD_Set
Field iBits:Int[32] End Type Zurück zu Lück(arg, Wortspiele sind einfach der Hass!) Zitat: #define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) #define __FD_ISSET(d, set) (((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) != 0) #define __FD_ZERO(set) \ ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set))) __FDELT(d), __FDMASK(d), __kernel_fd_set klingt wieder nach Sucharbeit! aus der select.h: Code: [AUSKLAPPEN] #define __FDELT(d) ((d) / __NFDBITS)
#define __FDMASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS)) Ergo Code: [AUSKLAPPEN] #define __FDELT(d) ((d) / 32)
#define __FDMASK(d) ((long int) 1 << ((d) % 32)) aus http://www.x86-64.org/lists/bugs/msg00066.html Code: [AUSKLAPPEN] typedef struct {
unsigned long fds_bits [(1024/(8 * sizeof(unsigned long)))]; } __kernel_fd_set; Ergo Code: [AUSKLAPPEN] typedef struct {
unsigned long fds_bits [(1024/32]; } __kernel_fd_set; So, das ganze etwas zusammen setzen(fühlt man sich ja fast wie bei Nip/Tuck)... Code: [AUSKLAPPEN] #define __FD_SET(d, set) ((set)->fds_bits[(d) / 32] |= (long int) 1 << ((d) % 32))
#define __FD_CLR(d, set) ((set)->fds_bits[(d) / 32] &= ~((long int) 1 << ((d) % 32))) #define __FD_ISSET(d, set) (((set)->fds_bits[(d) / 32] & ((long int) 1 << ((d) % 32)) != 0) #define __FD_ZERO(set) \ ((void) memset ((__ptr_t) (set), 0, 128)) Und da endet auch meine Entdeckungsreise durch den wilden Makro/C/Linux-Jungle! Ich habe jetzt die Schnauze gestrichen voll von allem, hochlebe Window mit WinSock! mfg olli Ich werf mich jetzt hintern Zug! |
||
vertex.dreamfall.at | GitHub |
![]() |
wunderkind |
![]() Antworten mit Zitat ![]() |
---|---|---|
<LOL> Alltag ![]() |
||
![]() |
MVB |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich habs noch nicht ausprobiert. Aber scheint ja was gutes geworden zu sein. Ich probiers am Wochenende mal aus.
Und hintern Zug passiert ja zum Glück nicht so viel wie vor den Zug. ![]() |
||
aquamonit.de|BlitzMax|MaxGUI |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ja, hintern Zug werfen kommt nur lustig wenn man einiges vorher getrunken hat...
Linux / Windows Version: http://vertex.art-fx.org/bnet.zip Küsst mir die Füße! Naja gut, ich habe bisher das ganze nicht ausgetestet, ich weiß sowieso nicht, ob ich die Funktionen einfach so einbinden kann. Deswegen seid ihr mal an der Reihe das zu testen. FD_Set Strukturen gehen zumindest manuell perfekt, ob Linux selber den Aufbau annimmt, ist eine andere Sache ![]() ![]() Wenn es Tester für MacOS hier geben sollte, dann wäre ich auch bereit für Mac zu portieren. An euren BMax Codes selber müsst ihr aber nix ändern. mfg olli |
||
vertex.dreamfall.at | GitHub |
![]() |
Phalastos |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi Vertex,
ich glaube da hast Du Dir langsam einen Orden verdient. ![]() Bleib am Ball, Du bist der Meister! Gruß Alex |
||
Forbiddenmagic - Warfare of Forgotten Power |
![]() |
regaa |
![]() Antworten mit Zitat ![]() |
---|---|---|
regaa hat Folgendes geschrieben: Wie immer kann ich über deine Arbeit nur staunen. Great Job.
8) |
||
UltraMixer Professional 3 - Download
QB,HTML,CSS,JS,PHP,SQL,>>B2D,B3D,BP,BlitzMax,C,C++,Java,C#,VB6 , C#, VB.Net |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
![]() Hatte heute den ganzen tag in der Höle des Löwens verbracht sprich Linux. Testdistributionen waren Red Hat 9 Textbasierend und Knoppix 3.4 c't Edition. Knoppix(mit KDE): Es läuft nur die alte IDE, 1.03 und 1.03B lassen sich nciht starten Es läuft nur der Core 1.01 Compiler. Core 1.03benötigt stdc++ 6 was ich für Knoppix nirgendwo gefunden habe. Habe schon ein paar RPMs ausprobiert mit rpm -i DasRPM aber nada, braucht irgendwie noch andere GCC Dateien. Also geht nur Core 1.01. Ersteinmal mit Print "Hello Linux!" probiert. Geht nicht. Dem fehlt ne G1 oder GI Datei. Klingt nach OpenGL. Knoppix wird also keine OpenGL Treiber haben oder so. Habe mal opengl.mod und so weiter als opengl nur umbenannt in der hoffnung das er sie nichtmehr mit einbinden wird(geht schließlich bei eigenen mods ja auch) aber auch da nada. Kann einfach nicht linken. Red Hat 9(text basierend): Das IDE nicht läuft ist klar. Es läuft auch nur Core 1.01 Compiler, mit den selben Fehlern wie unter Knoppix. Zumindest habe ich ein paar Bugs im Code gefunden(neue version ist bereits online). Ich wäre wirklich daran interessiert, ob bnet unter Linux läuft. Also wenn es geht, mal einer testen... mfg olli |
||
vertex.dreamfall.at | GitHub |
Gehe zu Seite 1, 2, 3, 4, 5 Weiter
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group