🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

winsock and MUD

Started by
8 comments, last by Sordith 23 years, 10 months ago
I''m working on a MUD, and ran into some winsock problems (using async sockets). For those who don''t know, a MUD is a text based RP game. three sample lines possible from client: ooc this is a global message kill dragon tell sordith nice mud you have here When i get my FD_READ message and call the recv function, I appear to be getting one word at a time, rather than the full line. Does anyone have any idea how I could parse my input to recive a full line rather than a split line? Thanks
Advertisement
That''ll happen with TCP, it likes to split up packets. In order to get around this, check the return value of recv - it gives you the amount of bytes received. Compare this to the size of the structure that you are reading data into. Keep reading data in to it until the sum of the amount of bytes received is equal to the size of the structure receiving the information.

-BacksideSnap-
quote: Original post by -BacksideSnap-
Keep reading data in to it until the sum of the amount of bytes received is equal to the size of the structure receiving the information.


The size of the data to recive isn't standard. Note the sample input lines:

28 characters: ooc this is a global message
11 characters: kill dragon
35 characters: tell sordith nice mud you have here


Edited by - sordith on August 21, 2000 3:16:10 PM
You have to have design a mechanism for specifying size of your data or delimit it.

For example 2 approaches are:

1. Have the first part of every message say how much data is coming in that message. Keep reading until you get all of it: then repeat.

2. Have each message delimited. So pick a byte you will never be sent from your client program. Once you find the first byte, keep writing until you see the 2nd, everything inbetween is your message.

Since most MUDs are playable via telnet, so I''d go with option 1.

If someone is playing via the Windows Telnet client, that is known for sending a packet for each letter you type! You can''t rely on the client sending data in line mode, or for it to send a whole line when it does.

The answer is simple:
1) Each time you read from a socket, append that data to a buffer.
2) Each time you''ve added to that buffer, search for a the end of line character(s). NOTE: this could be "\n\r", "\r\n", "\r", or "\n". All of these combinations should be accepted by your server.
3) Take everything from the buffer before the end of line, and process that as your command. The rest of the buffer should be kept for next time.

This is a lot easier if you use a custom String class as breaking apart the buffer becomes much more straightforward and cuts out all the pointer trickery.

Also, you should probably do something similar for output, as there is no guarantee that write() or send() will successfully send all your data, especially if you send more than 1 or 2 k at a time. So, you should write that into a buffer, and send as much of that as possible each time.
Thanks Kylotan, that''s exactly what I was looking for.
quote: Original post by Sordith

The size of the data to recive isn''t standard. Note the sample input lines:

28 characters: ooc this is a global message
11 characters: kill dragon
35 characters: tell sordith nice mud you have here


Edited by - sordith on August 21, 2000 3:16:10 PM


Doesn''t matter. Send using a sizeof () and check against that rather than the length of a string. You should be sending a struct across anyway.


-BacksideSnap-
quote: Original post by -BacksideSnap-
Send using a sizeof () ...
-BacksideSnap-



I have no control over the client. Since this is a pure telnet game, they can be using any telnet client they find (although you probably didn''t know that... sorry).

Everyone here has given the common method of reading it to a buffer and appending the buffer. Usually I support that method but there is an easier method.

If you leave the data in winsock''s read buffer by peeking you don''t have to deal with buffers. Just use read to peek. If there isn''t a return in the buffer leave the data in. If there is read upto and including the return (CR and LF depending on client) until you''ve read all of the complete lines.
For a good time hit Alt-F4! Go ahead try it, all the cool people are doing it.
quote: Original post by blue-lightning
Just use read to peek.



I tried this, but for some reason, a lf or cr wouldn''t show up until I removed all the data before it. I tried this with two clients and probably should have tried it with more. Putting it into a buffer, although a slight waste of memory, seems to be working. Thank you for the posts.

Sordith

This topic is closed to new replies.

Advertisement