Tcp Server/Client Sockets
Monkey Forums/Monkey Programming/Tcp Server/Client Sockets
| ||
I'm trying to figure out how to work with Tcp sockets. I've tried out the examples that come with Monkey X, but they don't help me that much. The problem is when a lot of data stacks up... when it's sent ontop of each other, it sorta creates a mess of data I don't know how to handle. Especially when the server runs faster than the client does! So I've got this example of my problem, and I thought maybe we all could work together to shape this into a sort of basic Tcp Server/Client Framework? I'm no good at network stuff, so this whole thing might be useless, but I really think Monkey X need some sort of solid network framework and I think that this could be turned into something good. In this example the client will send 3 messages to the server, which works fine. Then the server will respond with another 3 messages back to the client, and because the client runs slower than the server, the data will be messed up and things will end badly! You'll also see "RACE!" being printed and I have no idea what that is about... UPDATE: Seems like the newest Monkey X versions fixed that message! In client.monkey, if you remove If UpdateRate > 4500000 ThenThe client will run as fast as the server, which will "fix" the issue. This of course isn't a solution. This example code was made for the C++ Tool Target. CODE REMOVED Now found on BitBucket: https://bitbucket.org/Hezkore/monkey-x-tcp-module |
| ||
Alright, I've made some progress and figured out a few things. This seems to work pretty well right now, but any input is welcome! Keep in mind that a lot of things are in test/debug mode. I'll finish this up, clean up the code and eventually put this on BitBucket. CODE REMOVED Now found on BitBucket: https://bitbucket.org/Hezkore/monkey-x-tcp-module |
| ||
Wow. My god. Congratulations for your work. Thank you Golomp |
| ||
Thank you! It's not really ready to use yet and needs a lot of shaping up, but it's getting there! I'm going to remove as much DataBuffer slicing as I can. Add client join/part as packets for the server, as well as a error packet the server can send to the client. And also a ping packet that will measure client response time and test if they're still an active client. |
| ||
This has been turned into a module over at BitBucket: https://bitbucket.org/Hezkore/monkey-x-tcp-module It comes with a Server and Client example and should work on all targets that supports brl.socket, and it does everything asynchronously. I've gotten rid of a lot of DataBuffer slicing. The server now gets both a JOIN and a PART packet when clients connect or disconnect. You can disconnect clients with a custom error message. Ping packets are not in yet. Clients has a UserData Map you can store information in. And I've noticed that Floats are sent as Ints for some reason, not sure why that is... Any input is still welcome, and feel free to push commits to the repo! |
| ||
Nice stuff, I like it! Will play around with it. Thanks for sharing! :) |
| ||
@Xaron: If you're interested, at least as an example, I wrote this before. To actually use it, you'd need my other modules, though. That module's still experimental, but it works for both TCP and reliable UDP. And from what I remember, I had an internal-message system going, which supports pinging. Nothing "production ready", but if you find it useful, by all means take what you want from it. The main modules it needs are: * 'util' * 'eternity' * 'byteorder' * 'publicdatastream' Because there's several imports, and I haven't marked it as stable, if you want to use the module normally, you'll want to recursively clone this repository. Honestly, it's probably better to just look the code over yourself. |
| ||
Thanks, will check it out as well! :) |
| ||
very nice work! I'm playing around a little bit with your code. How do I send a broadcast to all connected Clients ? i have managed to code a little Chat. Everything's fine. When i start 2 Clients, it shows me that there are 2 Clients connected. now, I've changed: Server.StartPacket(PACKET_MESSAGE) Server.Packet.AddString(Packet.ReadString()) Server.SendPacket() '<<< shouldn't this now be kind of broadcasting to all? but my Server quits with mav. edit: Now I've recoded the servercode. And everything's fine. I can connect 2 different Clients. When i press Space, it sends a message, but only the sending client receives it's own message. |
| ||
It's been a long time since I worked on this, and I'm not by the compter today.... But I don't think the server just bounces the message to eveyone on its own. When you send a packet, you send it to the server and then you need to tell the server what it should do with that information. Like, all "chat" packets could be sent to all clients if you wish, but you need to code that. And all "login" packets (which you certainly don't want to broadcast to everyone) could be checked against your user database. Basically, the user doesn't have control over what's broadcasted or not, you code your server to handle all that. All messages are sent to the server where you have full control over what happens next. In the server you can see the line which goes something like SendPacket(From.Packet) Which means it just sends the packet back to whomever the packet came from. I believe that if you remove From.Packet, it might send to everyone. Or I can throw together a "send to all" example at some point. :) |
| ||
I missed this first time around, definitely going to have a look at this as it sounds great. Thanks for sharing! |
| ||
Hi, Ok, now I got it running with a very cheap solution. But it works. within the sending routine of Server-app: For Local i:Int = 0 Until Server.getClientCount() Server.StartPacket(PACKET_BROADCASTMASSAGE) Server.Packet.AddString(str) Server.SendPacket(i) Next I also added to TcpServer Class Method getClientCount:Int() Return ClientArray.Length() End Method I expacted to get only the number of connected Clients, but it returns the max number of possible Clients, so i also had to change the SendPacket Method of TcpServer If Self.ClientArray[client] <> null Packet._socket = Self.ClientArray[client].TcpSocket Packet._onComplete = Self.ClientArray[client] Self.PacketSendQueue.AddLast(Packet) Endif I may add a getConnectedClientID:int[]() returning all Client IDs which are connected to the Server, So you can do something like: Local cID:Int[] = Server.getConnectedClientID() For Local i:Int = 0 Until cID.Length() Server.StartPacket(PACKET_SECUREMASSEGE) Server.Packet.AddString(str) 'Send packet to specific client 'Leave empty to send to all clients Server.SendPacket(cID[i]) Next |