{"id":90,"date":"2016-03-20T14:20:09","date_gmt":"2016-03-20T14:20:09","guid":{"rendered":"http:\/\/blog.qubekwest.com\/?p=90"},"modified":"2016-04-14T18:33:58","modified_gmt":"2016-04-14T18:33:58","slug":"network-diversion","status":"publish","type":"post","link":"https:\/\/blog.qubekwest.com\/?p=90","title":{"rendered":"Network Diversion"},"content":{"rendered":"<p>In my head, QubeKwest is <em>always<\/em> a client\/server program. \u00a0Meaning that even a single player local game is going to be the client program connecting to the server program over localhost. \u00a0The fun part there is that it means that the client and the server can be located anywhere. \u00a0On a powerful computer, they talk to each other over a localhost network with both parts running on the same computer. \u00a0On lesser computers they talk to each other over an actual network with the client and server each being their own computer. \u00a0And in the case of playing with your friends, they talk to each other over the internet. \u00a0If I code it right, the game not only &#8220;won&#8217;t care&#8221; but it actually won&#8217;t even know the difference.<\/p>\n<p>Networking is a tricky beast and starting with the server makes the most sense. \u00a0A server can be coded in tons of different ways I&#8217;m sure, but the two that I have personally coded are the threaded approach and the asynchronous approach. \u00a0The threaded approach just uses the normal java.net.* things while the asynchronous approach uses java.nio.*. \u00a0If you&#8217;ve ever tried to code your own NIO version without help and pulled it off you are better at coding than me. \u00a0Simply put, I get the java.net.* stuff and my brain skips a step and stumbles the rest of the way down the stairs to end in a heap at the bottom when I try to understand the java.nio.* stuff. \u00a0Ok, that&#8217;s not fully true anymore, but it certainly was for previous attempts.<\/p>\n<p>For a little background on the differences between the two approaches, I present a couple of paragraphs that get a little deep. \u00a0In the threaded approach, your server has a full blown operating system thread to handle every single incoming connection from a client, and another one to act as\u00a0the server thread itself. \u00a0This is extremely heavy, not terribly scalable, and puts a pretty hard limit on the number of clients that can be connected at the same time. \u00a0Most modern operating systems support thousands of concurrent threads, but long before you get anywhere near that number, you start slamming into the overhead of switching between the threads you are using. \u00a0This approach is easy to code, easy to understand (if you understand how to play nicely with threads at least), and completely useless for large numbers of client connections.<\/p>\n<p>In the asynchronous approach, you create a semi-magical server with just a thread or two to handle all the work of responding to clients. \u00a0The magical part is that it doesn&#8217;t matter if there is one client connected or 1000, the number of threads the server uses to manage the whole thing doesn&#8217;t change. \u00a0For a most excellent explanation of how this works, go check out the <a href=\"http:\/\/rox-xmlrpc.sourceforge.net\/niotut\/\" target=\"_blank\">Rox Nio Server Tutorial<\/a>. \u00a0I used that tutorial to craft how my game server works and it is the best description of how to make Java NIO stuff work correctly that I&#8217;ve ever bumped into. \u00a0This approach is a little trickier to code, vastly more complicated to get your head around, and scales well since you don&#8217;t need tons of threads to make it work.<\/p>\n<p>This brings me to my diversion. \u00a0In all of the refactoring and playing with and confusing things and in general just blowing up of code that I did while writing an NIO server for QubeKwest, I managed to entirely lose track of how to use it and then I managed to substantially break it. \u00a0After seven months without looking at the code, I came back to discover that my network code was well and truly busted and that I had no clue how to fix it. \u00a0I started trying to follow the Rox Tutorial again on the code I had, but quickly found that my code was so different from the original that even that wasn&#8217;t useful.<\/p>\n<p>Then an idea popped into my head. \u00a0Start over. \u00a0I know, great idea&#8230; \u00a0but sometimes it&#8217;s just what you have to do. \u00a0In this case I decided to simply make a stand alone server that wasn&#8217;t connected to the QubeKwest code at all. \u00a0This approach eliminated the QubeKwest package structure, the broken code, the refactors I&#8217;d incorporated, and it allowed me to learn how the whole thing was supposed to work again. \u00a0All without further destroying the networking in QubeKwest.<\/p>\n<p>It took me a couple of days to get it to work properly because I was taking my time and making sure I understood the code I was writing. \u00a0When I thought I was done, I found that I was exactly one line of code short of having it work properly. \u00a0The code I&#8217;d produced was pegging\u00a0an entire CPU core to 100% (even without requests coming in) and didn&#8217;t respond to the client. \u00a0This is obviously not an ideal server since the goal would be to use essentially 0% of the CPU unless you are responding to something and of course to actually respond to things.<\/p>\n<p>Once I found the one line of code I&#8217;d missed, added it in, recompiled, and fired it up again, everything was suddenly behaving correctly. \u00a0Now I just need to refactor the code a bit in the stand alone version so it is a little cleaner, and then start integrating it into the QubeKwest network package. \u00a0It was an interesting couple of days, but at least I learned something and have functional code again.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my head, QubeKwest is always a client\/server program. \u00a0Meaning that even a single player local game is going to be the client program connecting to the server program over localhost. \u00a0The fun part there is that it means that the client and the server can be located anywhere. \u00a0On a powerful computer, they talk &hellip; <a href=\"https:\/\/blog.qubekwest.com\/?p=90\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Network Diversion<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-90","post","type-post","status-publish","format-standard","hentry","category-dev"],"_links":{"self":[{"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/posts\/90","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=90"}],"version-history":[{"count":2,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/posts\/90\/revisions"}],"predecessor-version":[{"id":92,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/posts\/90\/revisions\/92"}],"wp:attachment":[{"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=90"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=90"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=90"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}