simple network functions
BlitzMax Forums/BlitzMax Beginners Area/simple network functions
| ||
I have no experience with network code at all, and I am looking for some library or other that would enable me to add network communication between a server and perhaps up to 10 clients. Its for a turn based game, where the server will do some calculations based on dice rolling and then tell the client the outcome. The client informs the server about what the user is doing. I do not think, that it will envolve a lot of traffic, but since I have no knowledge about how networking works, I am hoping that someone can offer some advise and point me in the right direction towards something that is easy to implement and will not require prior knowledge other than knowing how to code generally. I am fairly knowledgeable when it comes to bmax, I just have not touched anything to do with networking. |
| ||
Maybe this could help you: http://blitzmax.com/codearcs/codearcs.php?cat=4&order=&asc=&lang_id=2 |
| ||
Its for a turn based game I suggest blitzmax socket streams then. They are very easy to use, and is perfect for use in turn-based games, however, not with mmo or fps. |
| ||
I don't really know what I am doing with this network stuff. Here is what I have so far, but its not really working, and I am a bit clueless as to what I am doing wrong. TYPES: Type TServer Field socket:TSocket Field port:Int Function Create:TServer(port:Int) Local server:TServer = New TServer server.socket = CreateTCPSocket() ' check to see if a socket was created, and if not return null otherwise return server If Not BindSocket(server.socket, port) Or Not SocketListen(server.socket) Then CloseSocket(server.socket) Return Null End If server.port = port Return server End Function Method close() CloseSocket(socket) End Method Method accept:String() Local message:String = "" Local clientname:String = "" Local client:TSocket = SocketAccept(socket) If client Then Local stream:TSocketstream = CreateSocketStream(client) clientname = DottedIP(SocketRemoteIP(client))+":" While SocketReadAvail(client) message :+ ReadLine(stream) Wend Return clientname+message Else Return Null ' no connection made End If End Method End Type Type TClient Field host:String Field port:Int Field socket:TSocket Field stream:TSocketstream Function Create:TClient(host:String,port:Int) Local client:TClient = New TClient client.host = host client.port = port client.socket = CreateTCPSocket() ConnectSocket(client.socket,HostIp(host),port) If client Then client.stream = CreateSocketStream(client.socket) Return client Else Return Null ' no luck creating client End If End Function Method send(message:String) WriteLine(stream,message) End Method Method recieve:String() If SocketReadAvail(socket) Then Return ReadLine(stream) End Method End Type SERVER: SuperStrict Import brl.stream Import brl.socket Import brl.socketstream Include "servertype.bmx" AppTitle$ = "SERVER" Graphics 320,240,0 SetClsColor 128,128,128 Local server:TServer = TServer.Create(112233) Local mess:String Repeat mess = server.accept() Until KeyHit(KEY_ESCAPE) Or AppTerminate() Or mess <> "" Cls DrawText mess,0,0 Flip WaitKey End CLIENT: SuperStrict Include "servertype.bmx" AppTitle$ = "CLIENT" Graphics 320,240,0 Local client:TClient = TClient.Create("127.0.0.1",112233) If Not client Then End While Not KeyHit(KEY_ESCAPE) If KeyHit(KEY_SPACE) Then client.send("Test") Wend I really appreciate any help I can get with this. What I would like to be able to, is to transmit messages between clients and server, where the server knows which client who sent the message, and it can react on this message and send a response back to the correct client. |
| ||
Well, TCP is a stream so per stream there is only one "place to come from". Just store the IP when you accept the connection in a datastructure that is meant to hold playername, ip and whatever else you might like (most likely you use a TMap and use the IP in as string as key to retrieve it. the object you put in would be your own TPlayer type or whatever you want to call it) |
| ||
This is probably the first time, where I have been at a loss with bmax, and up until now I have been able to live with the really poor documentation that comes with it. But that has been because the other things I have used bmax for, has been things where I have had prior knowledge. Networking is something I know absolutely nothing about, so I am starting with a clean slate. And now I really see why it really hinders people when the documentation contains absolutely no examples at all. How are someone to know where to begin when there are no info to read into. I really think that they should take a month or two out of what ever they are working on and write some useful examples. It would really make it a much easier language to dig right into and they would probably gain a lot of new users. But since that is unlikely to happen, I am left with the hopes that other users on this forum is kind to help or work my way through a lot of hours of trial and error. |
| ||
Socket information within BM would be worthless. Simply because different restrictions and capabilities are bound to them depending on the OS you use them on. So you will have to look for OS dependent informations on them, there is no general information that will help you working with them. That will most likely explain as well why most do not attempt Sockets but prefer existing networking libraries. Its definitely not easy if you have 0 technical background in that area and you will take quite some time (several months most likely) till you learned the ins and outs Hope that explains why BM has no informations on the sockets. It would be worthless, its not a language feature, but an OS one BM offers streams and GNet to use networking. Both are definitely better suited. GNet is little documented, but the networking streams work the same as the regular ones beside the connection part and are documented. You at best start out with them and read up on how you transfer information between different clients or client - server (like stuff on how such a message is structured with the MessageID and the like). Thats stuff not related to the networking but to your own network handling code within your application and therefor not documented as well as it has nothing to do with BM. BM takes care that the information is sent from A to B What you send, when you send it and how it is structured is up to you and there are many different pages on this topic |
| ||
I have spent some time looking at that GNet, and I have come up with the following, which works as far as sending information to the server. But what if there are more than one client contacting the server. How would I go about changing it so that it can know who is sending the data? Server: SuperStrict Local host:TGNetHost = CreateGNetHost() Local port:Int = 1234 Local address:String = "127.0.0.1" Local timeout_ms:Int = 10000 Local listen:Int = GNetListen( host, port ) If Not listen Then RuntimeError "GNetListen failed" Local remoteObj:TGNetObject Local objList:TList = New TList Local txt:String[32] Local num:Int[32] Graphics 320,240 While Not KeyHit(KEY_ESCAPE) Delay 10 GNetSync host objList = GNetObjects( host, GNET_MODIFIED ) For remoteObj = EachIn objList DrawText GetGNetString( remoteObj, 0 ), 10,10 DrawText GetGNetString( remoteObj, 1 ), 10,20 DrawText GetGNetString( remoteObj, 2 ), 10,30 DrawText GetGNetInt( remoteObj, 3 ), 10,40 DrawText GetGNetInt( remoteObj, 4 ), 10,50 DrawText GetGNetInt( remoteObj, 5 ), 10,60 DrawText GetGNetInt( remoteObj, 6 ), 10,70 Next Flip Wend CloseGNetHost(host) End Client: SuperStrict Const GNETSLOT_NAME:Int = 0 Const GNETSLOT_STATS:Int = 1 Const GNETSLOT_VITALS:Int = 2 Const GNETSLOT_LOCALMAPX:Int = 3 Const GNETSLOT_LOCALMAPY:Int = 4 Const GNETSLOT_WORLDMAPX:Int = 5 Const GNETSLOT_WORLDMAPY:Int = 6 Local host:TGNetHost = CreateGNetHost() Local port:Int = 1234 Local address:String = "127.0.0.1" Local timeout_ms:Int = 10000 Local connect:Int = GNetConnect( host, address$, port, timeout_ms ) If Not connect Then RuntimeError "GNetConnect failed" Local localObj:TGNetObject = CreateGNetObject:TGNetObject( host ) Graphics 480,360 While Not KeyHit(KEY_ESCAPE) Delay 10 GNetSync host If KeyHit(KEY_SPACE) Then SetGNetString localObj,GNETSLOT_NAME,"Character Name" SetGNetString localObj,GNETSLOT_STATS,"18,9,16,11,13,10" SetGNetString localObj,GNETSLOT_VITALS,"108,32" SetGNetInt localObj,GNETSLOT_LOCALMAPX,100 SetGNetInt localObj,GNETSLOT_LOCALMAPY,100 SetGNetInt localObj,GNETSLOT_WORLDMAPX,0 SetGNetInt localObj,GNETSLOT_WORLDMAPY,0 End If Wend CloseGNetHost(host) End I was thinking that I could use the first slot of the object and use the player character name and then react to that. But I am not sure about what to do when having to send data back to the clients. I am going to keep working on this and hopefully I will get some working code that will allow me to continue with the game idea. I just think that I need to have working network communication done before I move on. Any input on effective ways of dealing with this is highly welcome. |
| ||
You don't send data back on the same object. As for the other objects: when the player logs in on the server, create a local object there. This will then exist as remote object on the clients side. This has the very nice side effect that other clients can manipulate anything but their own beeing. You then only need to syncronize the local object and the corresponding client remote object and you are done. The alternative is to use the messaging system to send messages back to the player. As for easy retrieval of the gnet object of a given player: brl.map -> TMap and using the name as key. |
| ||
Isn't GNet Win32 only? Or was that GNetEx? |
| ||
there is no GNetEx at all. GNet is crossplattform and uses Pub.ENet as networking core. No problem with other platforms |
| ||
I have no experience with network code at all, and I am looking for some library or other that would enable me to add network communication between a server and perhaps up to 10 clients. Its for a turn based game, where the server will do some calculations based on dice rolling and then tell the client the outcome. The client informs the server about what the user is doing. I do not think, that it will envolve a lot of traffic, but since I have no knowledge about how networking works, I am hoping that someone can offer some advise and point me in the right direction towards something that is easy to implement and will not require prior knowledge other than knowing how to code generally. I am fairly knowledgeable when it comes to bmax, I just have not touched anything to do with networking. My BBStream Module might help with what you are requesting. |
| ||
I would prefer to use open code, not a module. There is just no way of knowing what is in the module code, and there is no way of making changes to the code within the module. Also, often with updates to bmax modules break and doesn't work anymore, and if for some reason the module becomes unsupported, then your are out of luck. |
| ||
I would prefer to use open code, not a module. There is just no way of knowing what is in the module code, and there is no way of making changes to the code within the module. Also, often with updates to bmax modules break and doesn't work anymore, and if for some reason the module becomes unsupported, then your are out of luck. Just suggesting. |
| ||
Yeah, I know and thanks for the suggestion. It looks like your module has all the bases covered, but for the above mentioned reason, its probably not for me. Its for a small sparetime project, so its not time critical, I can take my time getting to know what is needed, but I do wish it would have been easier than it appears to be. |
| ||
I created the following code for a turn based game: http://blitzmax.com/codearcs/codearcs.php?code=1908 It uses GNet so no external modules are needed. Is that may be of use to you? |
| ||
Thanks, I will take a look at it. |