BNetEx
BlitzMax Forums/BlitzMax Module Tweaks/BNetEx
| ||
![]() Network Module for Windows, Linux and MacOS Superstrict Object orientated Support for UDP and TCP Buffered Datapackages Domain to IP, IP to Domain Beta: ICMP Ping, Network Adapter Information, Broadcast German Helpfile Examples includet Open Source Easy Interface Current Version 1.70 Beta 2: http://vertex.dreamfall.at/bnet/bnetex170beta2.zip Older Versions http://vertex.dreamfall.at/bnet/bnetex170beta.zip http://vertex.dreamfall.at/bnet/bnetex166.zip http://vertex.dreamfall.at/bnet/bnetex165.zip http://vertex.dreamfall.at/bnet/bnetex164.zip http://vertex.dreamfall.at/bnet/bnetex163.zip http://vertex.dreamfall.at/bnet/bnetex162.zip http://vertex.dreamfall.at/bnet/bnetex161.zip |
| ||
New version with TCP Support!delted Server Example: deleted Client Example: deleted cu olli |
| ||
I chose your module for the networking in my game, and it has worked out great! I was able to get it to work on windows, mac, and linux. A couple of issues I ran across: 1: If Result = SOCKET_ERROR_ Then DebugLog err() Return 0 ElseOn both mac and linux, err() was undefined. I guess it isn't included in the libstdc or something. Commenting it out allowed it to compile. 2: For prototyping purposes, I used a text file to read in the ip address as a string, then connect to it. For example, Stream.SetRemoteIP(TNetwork.IntIP(hostIP))where hostIP is read in from a file as "192.168.0.100". The only catch was this didn't work with linux. My linux machine was able to host, but not connect to a remote host. I almost pulled my hair out until I tried reversing the segments, to get "100.0.168.192". It was then able to immediately connect to the remote host. I think this has something to do with a dns resolution happening (ie 192.168.0.100 = 100.0.168.192.in-addr.arpa.), but I could be mistaken. 3: TNetwork.StringIP(Stream.GetLocalIP()) On all 3 platforms, this returned 0.0.0.0. Each was done using different hardware. Keith |
| ||
Hi!Function err:Int() = "WSAGetLastError@0" Hmm sorry, this was only for me :) WSAGetLastError is the same I think as "errno" on Linux, on MacOS I don't know. htonl_(Self.RemoteIP) must be convert the IP in networkbyte order correctly. This is platformdepently. So I think Windows and Linux must convert from Little- into BigEndian and MacOS can use it so. TNetwork.StringIP(Stream.GetLocalIP()) = "0.0.0.0" Thats correct. You can get you local IP by using TNetwork.HostIP("") but I must programm HostIP :) Thank you for testing! Thats nice! cu olli |
| ||
So, new update... Tested all things, and it works correctly (on windows) (sorry, only with german help) UDP and TCP Streams are now buffered. Hmm just see the examples :P TCP-Server: deleted UDP-Client: deleted Netzwerkzeug: deleted cu olli |
| ||
Once a client connects to a stream, how does the server send info back when there are more than one client? Do you, 1.Send connect request to main server. 2.Create new udp stream on server connected to that client ip,port. 3.Send info meant for that client down that new udp stream? Or is there a way to do it down the one udp stream on the server? |
| ||
Yes, the best way is, to use only one udp stream. How does it work?: - A client must know the ip address and the udp port of the server - This client must set this ip address and port per SetRemoteIP (in association with TNetwork.IntIP()) and SetRemotePort and can send a request like "LOGIN Username" (using WriteString o.e. and using than SendMsg) - The server getting a message from a client. It receives the message per RecvMsg. This method set automaticaly the ip address and port of the client. You can get this ip address and port per GetMsgIP and GetMsgPort. You can save this important information in a TList. - The server sending a acknowlege like "OK" to the client by using SetRemoteIP and SetRemotePort with the ip address and port from GetMsgIP and GetMsgPort. You must remind that a server need only one udp stream for sending and receiving of messages from all clients. What client have send a message you can get per GetMsgIP and GetMsgPort. If the server want to send a answer, than it need to set the receiver(i.e. client) via SetRemoteIP and SetRemotePort. A client needs too only one udp stream for communication with a server(or more servers). cu olli |
| ||
This no longer compiles under 1.12, I hope you can fix it I get an "Internal Error" on this line If Addresses[0] Then Return ntohl_(Var(Int Ptr(Addresses[0]))) ' Error Else |
| ||
Thx Eikon, BNetEx 1.5 is out. Samples and Modulecode are updated. BMax has a bug with dereference a int-pointer, so I must work very trickie. So, I don't know, if this work on MacOS and Linux. Win32 work perfect. cu olli |
| ||
Is your 'bug' related to this? EDIT : Sorry, my bad, you're the one that started that topic ;] |
| ||
http://vertex.art-fx.org/bnetex161.zip New version 1.61: - RecvAvail: returns -1 = Error, else size of receiveable bytes - GetState: returns -1 = Error, 0 = Disconnected, 1 = All right cu olli |
| ||
Hi vertex, thanks for the regular updates. If I want to stick with using BNetEx 1.61 with BMax 1.10, I get an error on these two lines: Method Delete() MemFree(Self.RecvBuffer) ' Error (missing size) MemFree(Self.SendBuffer) ' Error (missing size) End Methodwould this be the correct way to solve the problem? MemFree(Self.RecvBuffer, Self.RecvSize) MemFree(Self.SendBuffer, Self.SendSize) |
| ||
Yes, BMax 1.12 don't need the size parameter in MemFree. cu olli |
| ||
hi! Does all the bnetex features works under MacOS and Linux too? Does is possible to have a english version? :) Bye! |
| ||
I hope :) A english version? Hmm, no :P Hard work to write an english document with my grammar :) cu olli |
| ||
eh eh! Your english isn't so bad... for me is much better a bad grammar than german comments ;) Anyway... does is possible to send anonymous UDP packets? i.e without indicating the source IP? |
| ||
Hmmm, I haven't any time for a documentation, but there are not so much commands... Anonymous packets? No, not with BNetEx. To send a anonymous packet, you must work with raw sockets. You must know, how Ethernet?, how IP and how UDP are structed. But I'am interested in it :) cu olli |
| ||
hmmm... raw sockets and anonymous packets... a perfect upgrade for a BnetEx 2.0 release ;) |
| ||
Vertex, please see the e-mail I sent you. I am running into a big problem that's keeping me from moving forward with my project. BNet will crash if you try to SendUDP to an invalid IP more than once, and SendUDP returns nothing to let you know whether a problem has occured.WriteByte Stream, 0 SendUDPMsg Stream, IP, Port ' IP is not set to receive ' Resend WriteByte Stream, 0 ' "Error writing to stream" crash here occurs in stream.bmx SendUDPMsg Stream, IP, Port ' Same invalid IP and PortThis means if you have any kind of resend routine in place, and someone closes the client with CTRL+ALT+DELETE or some other method that doesn't send a QUIT packet, the server and all remaining clients will crash with the server's first resend to the invalid IP. Please look into this. |
| ||
is it possible to host a server and connect to it on the same computer? This is a really important functionality if you want to divorce your game logic from the server completely that seems to be missing from GNet. |
| ||
Eikon: I'll make you a new BNet module. To debug the old module is complicated. Will: Yes, it is possible. You can too host a server and connect to it in the same program. cu olli |
| ||
Great! I guess I'll have to use BNet then, since GNet can't do that. |
| ||
Hi Vertex, thanks for the response. To anyone who is having the same problem, I fixed it by editing out the line in stream.bmx's WriteBytes function that throws the "Error Writing to Stream" exception, and rebuilding modules. I made it simply return false instead. The only problem is that this seems to have created a small memory leak, though this may be attributed to something else, I'll have to investigate further. |
| ||
The UDP Functions are ready, I must test it now. cu olli |
| ||
http://vertex.art-fx.org/bnet150.zip Please test it. There are only UDP functions + CountHostIPs and so on. DottedIP -> StringIP and in addition IntIP() to BlitzBasic. cu olli |
| ||
Hey Vertex. I'll take a look and get back to you soon, thanks |
| ||
http://vertex.art-fx.org/bnet160.zip Now with TCP Functions. cu olli |
| ||
What are all the features of BNet ? Is there a documentation ? Are there examples ? What is the to do list for this module ? |
| ||
The features of BNet are the same as Blitz3D/2D/Plus without DirectPlay. The documentation you also can find here: http://blitzbasic.com/bpdocs/command_list_2d_cat.php?show=TCP%20(Network) http://blitzbasic.com/bpdocs/command_list_2d_cat.php?show=UDP%20(Network) So examples can find anywhere :) Normaly, this thread is not for discussing BNet but BNetEx. BNetEx is the more logical and object orientadet advancement of BNet. cu olli |
| ||
What are differences between BNet and BNetEx in features ? What are differences between Bnet(Ex and co) and ENet (the network official module) ? |
| ||
BNetEx is object oriented. |
| ||
The last version of BnetEx is the 1.61, and it is aged of 2 months. Is it the last version ? What are future features in dev ? |
| ||
Future features? In germany we would say "das wäre Schnickschnack" :) BNetEx is, like IMurDOOM already sayed, completly object orientated. ENet = SocketStreamModule? If yes, than this is in my view the bad alternate to Blitz3D. cu olli |
| ||
What is the english for 'das wäre Schnickschnack' ? Vertex, your module is so good ! It is as well as Blitz3D 's network module Good ! Very Good ! |
| ||
nice 2 have, doesn't matter, unnessesary, ;D IMurDOOM |
| ||
Vertex, The new version is great, thanks for all the work you put into it. I have a question about routers/firewalls. Is there a way for a server to receive traffic on the UDP host port without having to manually forward it in my router settings? |
| ||
Hi! If I understud you right: No, you can't manipulate in the application layer the router settings. That is good :) Progi1984: "Schnickschnack" -> engl. "Knick-Knack" cu olli |
| ||
Another little question... what's the maximum size allowed for a single UDP packet? |
| ||
http://vertex.art-fx.org/bnetex162.zip Now, the limit is < 65 KByte to send a message in one part. cu olli |
| ||
I have done a brief translation of the bbdocs into english (using bablefish). I will post a link to it if vertex is ok with it :D It's not perfect, as I have not used the lib yet, only just deceiding to take a look after realising gnet does not do what I want :( cheers |
| ||
http://vertex.art-fx.org/bnet/bnetex162.zip sorry, fileserver crashed today, so have build a new index page and restructure the filestructure. peltazoid: hmm, ok, i will try to translate it. cu olli |
| ||
thanks for this module. its very handy! :) |
| ||
I have a translation of 162. i can send you the new source if you want, send me your email :D |
| ||
I was just checking out bnet because I wanted something b3d's networking rather than oop, but the udpserver demos calls a function that does not exist. namely InitNetwork(). Any ideas? |
| ||
New Version 1.63 http://vertex.dreamfall.at/bnet/bnetex163.zip Working german documentation, renewed examples, new module scope Vertex.BNetEx and new license(modified MIT). The new license say only, that you have to name the author and co-author of BNetEx(see doc/commands.htm). BNetEx is furthermore open source and free. cu olli |
| ||
The ZIP seems to be corrupted, I can't extract it. |
| ||
Please try again, my stupid ftp client seems to be doesn't work. cu olli |
| ||
Thanks, this time it works, and thanks for this great module (I've been learnt much from it) |
| ||
Sorry for the newbie question, but can someone tell me how to install this. I have just had a clean install of Blitzmax and I have added the directory bnetex.mod to BlitzMax\mod\pub.mod but when I run the example I get the error "Compile error can't find interface for module `Vertex.bnetex` " |
| ||
You have to put it under vertex.mod/bnetex.mod as described above. Pub / BRL are only for official modules not for 3rd party modules. |
| ||
Thanks for the help, got it working now. tried searching for it everywhere but just couldn't find it. Maybe I should go through the help files again |
| ||
Oh, sorry, BNetEx v1.64 have included a little readme.txt http://vertex.dreamfall.at/bnet/bnetex164.zip (added Method Flush in TNetStream) cu olli |
| ||
New Version 1.65 http://vertex.dreamfall.at/bnet/bnetex165.zip Now, you can receive and send packages up to 65 KByte for TCP and UDP. Thanks to IMurDOOM for this note! cu olli |
| ||
Cool to see it is still improving. Are you sure your folders or readme.txt in 1.65 are right? ;) |
| ||
Thank you! Hmm, whats wrong with the directory structure/readme? cu olli |
| ||
Seems to me as if it missed a 'bnetex.mod' directory. |
| ||
Oh, yes, fixed :P |
| ||
Current Version: vertex.dreamfall.at/bnet/bnetex166.zip Fixed bug for Linux. Based on the bug in pub.stdc with declared false values for SOL_SOCKET_, SO_RCVBUF_ and SO_SNDBUF_(values are only valid for Windows) Using pselect on Linux (see linux.c) with a defined signalmask. Testesd successfull with Kubuntu and Debian. cu olli |
| ||
hey this module looks great, stupid question but i'm not home to check. can i simple do : Create Socket via TCP connect to (ip address, port) send data / receive data. only reason i ask is that i have some issues with tStream connecting direct to an IP with having a host name. cheers |
| ||
Yes you can:GLobal Stream:TTCPStream Stream = New TTCPStream Stream.Init() Stream.SetLocalPort() Stream.SetRemoteIP(TNetwork.IntIP("127.0.0.1")) Stream.SetRemotePort(80) Stream.Connect() Stream.WriteLine("Hello, world!") While Stream.SendMsg() ; Wend While Stream.RecvMsg() ; Wend Print(Stream:ReadLine()) cu olli |
| ||
Hey thx, did it very well indeed, let me connect to a msn server and login to retrieve a buddy list :-) |
| ||
Hello Vertex This code run in 165 version, but in 166 version I get this message "Can't create socket" SuperStrict Framework Vertex.BNetEx Import Brl.StandardIO Global Stream : TUDPStream Try Stream = New TUDPStream If Not Stream.Init() Then Throw("Can't create socket") Stream.SetLocalPort(1234) Repeat If Stream.RecvAvail() Then While Stream.RecvMsg() ; Wend If Stream.Size() > 0 Then Print("Message from:") Print(" - IP = " + TNetwork.StringIP(Stream.GetMsgIP())) Print(" - Port = " + Stream.GetMsgPort()) While Not Stream.Eof() Print(">"+Stream.ReadLine()) Wend EndIf EndIf Forever Catch Exception:Object Print("Error") Print(" " + Exception.ToString()) End Try If Stream Then Stream.Close() Print("~n- ready -") End |
| ||
What OS do you have? |
| ||
I have OS X |
| ||
Oh, sorry, I can't test it on OS X :( There is the following new part on BNetEx: ?MacOS Const FIONREAD : Int = $4004667F Const SOL_SOCKET_ : Int = 1 ' Not sure! Const SO_SNDBUF_ : Short = 7 ' Not sure! Const SO_RCVBUF_ : Short = 8 ' Not sure! I have the values for Windows an Linux. I thank, that the constants the same as Linux, but I'am not sure. Do you have any *.h files for OS X that defines this constants? cu olli |
| ||
Hi Vertex Sorry, I haven't found a file *.h with those constants. I have tried to looking for Internet and only I have found the values of linux. |
| ||
Do you looking for sys/socket.h ? SOL_SOCKET, SO_SNDBUF and SO_RCVBUF are important, FIONREAD is right I think(becouse it runs in v1.65) http://fxr.watson.org/fxr/source/bsd/sys/socket.h?v=xnu-517#L121 You can test it with ?MacOS Const FIONREAD : Int = $4004667F Const SOL_SOCKET_ : Int = $FFFF Const SO_SNDBUF_ : Short = $1001 Const SO_RCVBUF_ : Short = $1002 Replace the old code with this, and recompile the module. But I'am not sure if this header file is written for MacOS X. cu olli |
| ||
Ops!!! X) Thanks Vertex, now run OK!! |
| ||
Thanks for testing! The next update will come with new constant values and maybe broadcast support and ping(ICMP Echo Request) function. cu olli |
| ||
Your modu works really well. I have done TCP/IP CHAT using of server the computer of my house. Now we are using it in my job. Work well under OSX, WINDOWS and LINUX Good work. |
| ||
Is there an English translation of the doc yet? I'd really like to use this, at the moment I am making direct Win32 calls to do UDP communication and I want to switch to something cross platform. My ability to read German (while it is a beautiful language) is somewhat... lacking however. |
| ||
No, there is no english translation because my english is to bad for it. I can write an english help, but you get an translation in form of posts you see above by me. I'am testing at the time the broadcasting functionality. The first test sending 3 as 1 message to the clients and I haven't any explanation for it. cu olli |
| ||
vertex... what do you mean? broadcasting on local lan is still achieved when sending to eg 192.168.0.255 (just cut the last part of the local ip and add 255). Now all in the LAN receive the packet? If you mean "broadcasting" to all clients... then I used your code, saved the packet before sending and then sent it to all clients I know (each time restoring the "buffer" after having sent to one of the clients). If I didn't understand the thing you want... you may also write your answer in German - so I may be able to give some suggestions too. bye MB |
| ||
http://msdn2.microsoft.com/en-us/library/ms740148.aspx#for_sockets_using_ip_(version_4)Const BROADCAST_ADDRESS : Int = $FFFFFFFF '... Method SendMsg:Int() Local Enable:Byte, Write:Int, Result:Int, Temp:Byte Ptr If Self.Socket = INVALID_SOCKET_ Or .. Self.SendSize = 0 Then Return 0 If Self.RemoteIP = BROADCAST_ADDRESS Then Enable = True Else Enable = False EndIf If setsockopt_(Self.Socket, SOL_SOCKET_, SO_BROADCAST, Varptr(Enable), 1) = .. SOCKET_ERROR_ Then Return 0 Write = Self.Socket If selectex_(0, Null, 1, Varptr(Write), 0, Null, 0) <> 1 .. Then Return 0 Result = sendto_(Self.Socket, Self.SendBuffer, Self.SendSize, .. 0, Self.RemoteIP, Self.RemotePort) If Result = SOCKET_ERROR_ Or Result = 0 Then Return 0 Else If Result = Self.SendSize Then MemFree(Self.SendBuffer) Self.SendSize = 0 Else Temp = MemAlloc(Self.SendSize-Result) MemCopy(Temp, Self.SendBuffer+Result, Self.SendSize-Result) MemFree(Self.SendBuffer) Self.SendBuffer = Temp Self.SendSize :- Result EndIf Return Result EndIf End Method This is my actual SendMsg method in TUDPStream. When I sending a "Hello, world!" message to one specific port, the socket with this port receive 3 times message from the same ip and port. cu olli |
| ||
its not msdn-like in my code ;D:Function GetBroadcastIP:String(ip:String) If Len(ip$)>6 ip$=ip$ Local lastperiod:Int=1 Local period:Int =0 For Local t:Int=1 To 3 '; 4 Zahlengruppen, aber die letzte muss weg period=Instr(ip,".",lastperiod) lastperiod=period+1 Next Return Left(ip,period)+"255" Else Return "" EndIf End Function Method SendUDPMsg:Int(iIP:Int, shPort:Short = 0) Local oldIP:Int = Self.remoteIP Local oldPort:Short = Self.RemotePort Self.RemoteIP = iIP Self.RemotePort = shPort Local returnvalue:Int = Self.SendMsg() Self.RemoteIP = oldIP Self.RemotePort = oldPort Return returnvalue End Method .... stream.SendUDPMsg TNetwork.IntIP(GetBroadcastIP(MyIP)), HOSTPORT You naturally could also make a new method/function (sendBroadcastMsg). Another way would be to store all IPs of the clients...and then send and send and send... but this time you send the packages, not the switch which is coordinating everything. Positive aspect would be, that only the specific IPs get the packages. In german: Die .255 ist die Broadcastadresse in jedem Lan... weswegen die "GetBroadcast"-Funktion auch die letzte Zahlengruppe wegschneidet und eine 255 anfuegt. Nun sendest Du ueber Deine SendMsg-Funktion einfach normal Dein Paket - nur stellst Du vorher als Empfaenger-IP die x.x.x.255 ein. bye MB |
| ||
I have no experience with this, becouse I have only one PC. But I know, to send a message to a broadcast address i.e. 192.168.178.255 send a broadcast message by other users. IMurDoom from the german board contacts me and quest me, if I can build in a function to calaculate the network class and based on this a function to calculate the broadcast address. But at this time, network classes don't play any role. The broadcast address can only be computed by a given subnet mask like 255.255.255.0. I haven't found any berkley socket standard function to detect the subnet mask. But: BroadcastAddress = MyIP | ~SubnetMask Broadcasting is also defined by the broadcast address 255.255.255.255 i.e. $FFFFFFFF. I don't know if this address works only when broadcasting is activated by setsockopt. cu olli |
| ||
ok, having read: http://de.wikipedia.org/wiki/Broadcasting I know what you want to say. But if this $FFFFFFFF doesn't work, the fallback would be to use the local-lan-ip and cut off the last part to replace it with 255 - so it only works in your own network - but this is the way a lan-game should work, if your clients are in different networks, the game wont work unless they play online. So the solution wouldn't be the correct one for your module, but the working one for coders - I don't know a network-configuration with different networks - none of my buddies uses such a setup with different subclasses without setting up a conversion like in VPNs - so 192.168.0.x and 192.168.1.x can work together without hassle - they all accept the 192.168.0.255 to broadcast. Another thing next to broadcast may be multicast...: http://de.wikipedia.org/wiki/Multicast bye MB |
| ||
Thank you for this impulse. On searching for broadcasting I've found http://www.zotteljedi.de/ respectively http://www.zotteljedi.de/doc/socket-buch.pdf On the first impression a very nice socket documentation that I will read in the soon. But one thing: Yes, this limited broadcast to 255.255.255.255 its not the solution. It must be a concret local area network broadcast address like 192.168.178.255 AND a enabled flag SOL_BROADCAST(on other way, the packages will ignored). So I need a platform independent function to get the subnet mask(but it seems like, there is no bsd functionality fot it) cu olli |
| ||
New Version 1.70 Beta: http://vertex.dreamfall.at/bnet/bnetex170beta.zip The Mac OS bug in TNetstream.Init is fixed. New: TAdapterInfo, TNetwork.GetAdapterInfo, TNetwork.StringMAC, TNetwork.Ping, TUDPStream.SetBroadcast and TUDPStream.GetBroadcast. It is a pure beta version becouse I don't know if works on Mac OS. TNetwork.GetAdapterInfo and TNetwork.Ping needs administrator/root rights. Tested successfull on Windows and Linux. Please take a look on examples/ping.bmx and examples/adapter.bmx cu olli |
| ||
Does the lib supports reliable UDP? If not, would it be easy to add this?? |
| ||
It does not support them by its own... but it is hmm fairly easy to write your own class handling the resend of packets which did not get acknowledged by the receipient. bye MB |
| ||
It's not supported becouse BNetEx is a lowlevel network engine. You have to program your own higher level protocol with id numbers, acknowleges, checksums, messages ques and so on. I've found a little bug for Linux version: Fixed in http://vertex.dreamfall.at/bnet/bnetex170beta2.zip (SO_BROADCAST defined in Pub.StdC $20 not working for Linux - 6 is needed) Also I think, that TNetwork.GetAdapterInfo don't need root/administrator rights. cu olli |
| ||
Any chance to see a binary file transfer example ? |
| ||
fraggit, I wish I saw this earlier I wouldnt have written me own max networking module :) |
| ||
Any chance to see a binary file transfer example? I would really appreciate such an example as well, is it even possible to do this? |