Jump to content
  • Advertisement
Sign in to follow this  
Etyrn

Advice needed: Keeping winsock thread safe - Avoiding "if(Connected)"

This topic is 4424 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Okay, well I'll start off with the easier problem. I have a Winsock wrapper class currently, and 2 certain functions in it. One is called "Connect" and the other is called "Disconnect". Of course, if Connect were to call while already connected, that'd be a crash. Same for Disconnect trying to call when already disconnected. To avoid this, I've made a boolean called "Connected". When Connect successfully runs, it's set to true, and when Disconnect successfully runs, it's set to false. The problem with this is, I flat out don't trust it. I'm sure it won't be too long until common bugs occur with it being false, while connected, then Connect's called again and such. What I'm looking for is some sort of function I could use that would check if the client is really in fact connected to the server, and instead of if(!Connected) I could have something like if(!CheckConnection()). Next, I'm wondering how I should go about keeping my Winsock class thread safe! Since I don't want to halt the client's rendering functions just to write to the socket, I'd rather multithread. Though I don't know the best way to go about doing this! Like, I could have say a loop that goes through send's and recv's while while the client runs and then write to the send buffer outside of the loop. But this would result in something being in the middle of being written, then sent from the other thread. No good. I could also just do _beginthread() client->network->WriteByte32(120322); But, if I did that for all of them, then if the code's fast enough I'd have 2 threads trying to write different numbers to the buffer at the same time. So I'm kinda confused here on what I should do to keep the client fast, efficient, and overall thread safe. Thanks, everyone! -Etyrn

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
Use mutex's inside the class, then use locks and unlocks inside the member functions so as the functions can not corrupt data.

Share this post


Link to post
Share on other sites
To not block when sending or receiving, you can use select(), or non-blocking sockets. Multi-threading is not strictly necessary (and, for large systems, isn't even necessarily a good idea).

You can probably use the function getpeername() to test whether a socket is connected or not. However, that's not exactly a high-performance function.

Ask yourself this question: why would your code call Connect() more than once on the same socket? Where did it get the socket from the second time, and why is it calling Connect() on it again?

And, also, why would the code crash if you call Connect() more than once? Are you talking about throwing exceptions, or not dealing gracefully with the error result from the call to ::connect()? Wouldn't it be easier to just fix those bugs?

Share this post


Link to post
Share on other sites
Quote:
Original post by hplus0603
To not block when sending or receiving, you can use select(), or non-blocking sockets. Multi-threading is not strictly necessary (and, for large systems, isn't even necessarily a good idea).

You can probably use the function getpeername() to test whether a socket is connected or not. However, that's not exactly a high-performance function.

Ask yourself this question: why would your code call Connect() more than once on the same socket? Where did it get the socket from the second time, and why is it calling Connect() on it again?

And, also, why would the code crash if you call Connect() more than once? Are you talking about throwing exceptions, or not dealing gracefully with the error result from the call to ::connect()? Wouldn't it be easier to just fix those bugs?


Well, I suppose the name Connect() is a bit misleading. I didn't really mean the Winsock defined one. What it does is all of my Winsock initializing, and of course connecting. As for calling more than once, say you want to log into your character. Enter your account data, then "enter" and Connect() is called to check with the server that it's all good. Character list comes up, and you wanted to go on a different account. So you close it, Disconnect(), and call Connect() again to login.

I also do have error handling, like if say Winsock's connect function fails to connect the server (like if it were offline). Also it calls WSACleanup when this happens, as well when Disconnect()ing. And Disconnect()ing also closesocket's the socket. So, yeah. Connect has a reason to be called more than once. :)

Also, thanks for the getpeername() idea. It may be slow, but I'd only be calling it every few minutes or so. Or maybe some sort of system when the client doesn't receive anything from the server for a little while, it checks.

And last of all, I'll give a shot at setting up my program with ol' FD_SET. Thanks a bunch! You too, Mr. Anonymous.


-Etyrn

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!