Networking in C++ Part #2: MMO Client/Server, ASIO, Sockets & Connections

Поділитися
Вставка
  • Опубліковано 23 гру 2024

КОМЕНТАРІ • 248

  • @czolus
    @czolus 4 роки тому +93

    "In this case, its quite safe, as I programmed it" -- famous last words ;)

    • @dandymcgee
      @dandymcgee 3 роки тому +1

      I was going to comment basically this exact same thing.. but instead I'll upvote yours. :D

    • @connerdassen7808
      @connerdassen7808 3 роки тому +1

      I think accidentally coding a virus would be challenging

  • @danieldinnie5003
    @danieldinnie5003 4 роки тому +88

    I read one of your posts about how difficult it was to start and at one point you didn't know if UA-cam was for you. I'm glad that you carried on. You have a cool channel. You are a smart man, and you are a creative programmer. Keep it up and stay happy.

    • @javidx9
      @javidx9  4 роки тому +32

      Thanks Daniel, comments like that make it all worthwhile!

    • @justinhardee82
      @justinhardee82 Рік тому

      Yeah, I'm in college. Fell in love with programming, and cannot stop researching it. I even got used to sleeping every other day to get more hours in the week to study. This one was a bit daunting, but after about 5 days of solid network programming for windows, and making a simple client and server, this one is finally making sense, as all of your videos do, if not the first time, then the second or fifth time lol.. Ur awesome man, I appreciate everything you do, my university ain't teaching me half of what you do. I am becoming a better programmer, particularly in part by your videos specifically. Thanks! @@javidx9

  • @javidx9
    @javidx9  4 роки тому +120

    Hello! Due to some IRL scheduling, I've brought forward next weeks video to now! This does mean there will be a gap before Part#3. Anyway, this video and the accompanying code is enough to start tinkering with in the meantime should you choose to. Though be aware it isnt ready for production - there is no security, and as its incomplete, it consumes 100% processor, and there is a memory leak too.

    • @martinfinne7259
      @martinfinne7259 4 роки тому +11

      Sounds like any modern game in early access, no security, resource hungry, and eats memory for breakfast :-)

    • @Ryan-xq3kl
      @Ryan-xq3kl 4 роки тому

      I havent started this series but I was wondering if it can be applied to 3D games in a similar way?

    • @powerclan1910
      @powerclan1910 4 роки тому +5

      @@Ryan-xq3kl the fact that your game is 3D or 2D doesn't decides your networking connection. Your networking code is mainly defined by time and stability requirements

    • @raskine
      @raskine 4 роки тому +1

      Looking forward to part 3!!

    • @antidotcb
      @antidotcb 4 роки тому +2

      ua-cam.com/video/UbjxGvrDrbw/v-deo.html
      You have a bug: net_server.h:112: m_deqConnections.erase(.... - it will remove nothing, as client isn't a reference, so the shared_ptr in deque wasn't changed by previous lane, and it still contains a valid ptr.

  • @guteksan
    @guteksan 2 роки тому +23

    Two things:
    1. I believe there's an error at 29:00 regarding checking whether we should read the body. It checks if header.size>0, but recall that header.size contains the size of the whole message (the header + the body, see: Part 1, 33:57). So in ServerPing scenario, the ping message should consist of 16 bytes (8 B header and 8 B body). SimpleClient writes a 8-byte body, but sets header.size to be 16. So the SimpleServer expects 16 bytes of body, and since only 8 are sent, it gets stuck.
    Surprisingly the initial ServerAccept message was received correctly. It's because when we set header.id to ServerAccept, we did not update the header.size and left it at 0.
    I think the simplest way to correct it would be to correct message& operator >, and replace `msg.header.size = msg.size()` with `msg.header.size = msg.body.size()`.
    2. This 'Windows-way' to read keys pressed (around 40:00) is kind of discouraging Linux users, since it is not that easy to achieve sth, similiar in Linux, as there are no direct equivalents of GetAsyncKeyState(). It is however possible to have a solution working on both platforms, and thanks to asio itself! I adapted the solution: stackoverflow.com/questions/52308998/read-from-keyboard-using-boost-async-read-and-posixstream-descriptor to react to characters '1' and '3' (of course, reading from STDIN requires confirming the input with Enter, while the Windows solution reacts directly to pressed keys). One more thing would be to create additional thread to asynchronously start io_service.run().

    • @RTSEnjoyer
      @RTSEnjoyer Рік тому

      thank you so much bro

    • @debsarkar4893
      @debsarkar4893 Рік тому

      bro u are an absolute legend thank you so very much

    • @aqertis4075
      @aqertis4075 Рік тому +1

      Nice catch! For the first issue, I think it would be better to change ReadHeader to correctly account for the header size instead of changing how we define header size entirely.
      To do this, just change 'if(m_msgTemporaryIn.header.size > 0' to 'if(m_msgTemporaryIn.header.size > 8', and change the following line from 'm_msgTemporaryIn.body.resize(m_msgTemporaryIn.header.size)' to 'm_msgTemporaryIn.body.resize(m_msgTemporaryIn.header.size - 8)'.
      This way, we keep the interpretation of header size consistent with how it was previously defined (header + body). By changing the > operators, it changes size's definition to be just the size of the payload.

  • @shinnok4941
    @shinnok4941 4 роки тому +26

    Hey David! I recently came across your channel by accident, and I hardly understand anything, but you are so calm and clever, that your videos are kind of magnetic. Remember that it's not just your content that is attracting audience.

  • @jjones503
    @jjones503 4 роки тому +4

    Hours and hours studying to learn this stuff from google, fail. Two short videos from you, succeed. You are most epic my dude.

  • @simonclark8290
    @simonclark8290 2 роки тому +5

    Even as a very experienced modern C++ softy just wanting to speed date the ASIO API I've really found this to be an excellent series. First class tutorial and explanation.

  • @VmsCentral
    @VmsCentral 4 роки тому +9

    21:10 - probably use of 'std::numeric_limits::max()' instead of -1 will be warning less at some compilers.
    22:53 - folks, try to change port if some one of visitor of this channel got an exception at the binding (WSAEACCES at Windows) while execution of Server constructor (actually basic_socket_acceptor). In my case 6000 was fine instead 60000.
    23:00 - this actually offtop for this video, however if you press cancel (for example you not an administrator of computer where you develop this program and do not know password of first one), and re-run program from Visual Studio you can still connect at putty.
    25:40 - in section you call critical, for some compilers (CLang) order must be same like in member list, and m_nOwnerType should be too, at least with default value. Otherwise some compiler show warning here.
    38:35 - major interesting here to make constructor and destructor of client_interface class public. They was left with default access (private) at 53:17 in part 1. Red underline at 'c' variable in video also indicate that moment.
    41:44 | 44:34 - send only in connection class. So should be 'm_connection->Send(msg);' instead 'Send(msg);'. That moment already fixed in source from GitHub.
    Unfortunately video version of code do not grant full access to possibility (answer from server if showed at client - do that only once) that was show in this part, probably according to off frame editing, so source for GitHub should help with that.

    • @georgemorales4208
      @georgemorales4208 2 роки тому +1

      Love u mane

    • @__hannibaalbarca__
      @__hannibaalbarca__ 7 місяців тому

      Thanks you man, two days to understand one exception ASIO_…PARAM. But is just change 60000 to 6000.

  • @isaac10231
    @isaac10231 4 роки тому +36

    As if the musical version of ASIO wasn't enough of a headache for me, it also share a name with C++ stuff too? Wonderful.

    • @beatrute2677
      @beatrute2677 4 роки тому +5

      The austalian version of the CIA is called ASIO.

    • @isaac10231
      @isaac10231 4 роки тому +1

      @@beatrute2677 I hope they function better than the ASIO driver lol.

    • @buzzdx
      @buzzdx 4 роки тому

      @@isaac10231 never had any problems with the asio drivers, what gives you headaches with them?

  • @omfgbunder2008
    @omfgbunder2008 4 роки тому +40

    "Because you all write awesome code" 😂😂😂😂😂

  • @Codeaholic1
    @Codeaholic1 4 роки тому +5

    I tried asio in the past for a simple networked application. There's a lot of complexity here, specifically having each task reprime the state machine seems odd. But I got it all working.
    I appreciate your explanation. It makes some of the things I didn't fully understand clearer.
    It also strikes me that there are similarities between this design and the actor pattern.

  • @wolpumba4099
    @wolpumba4099 4 місяці тому +1

    *Summary*
    This video focuses on building a functioning client-server system with ASIO and the framework outlined in Part 1. Here's a breakdown:
    *1. Server Functionality & Design* (1:09)
    * The server must handle:
    * Accepting client connections (1:14)
    * Handling client disconnections (2:10)
    * Implementing game logic (2:16)
    * An asynchronous `asio::acceptor` (10:38) object continuously listens for connections.
    * The server needs a task to keep the ASIO context alive: continuously wait for and handle client connections (10:38)
    *2. `Server` Interface* (1:09)
    * A template class designed for inheritance by user's application logic. (3:00)
    * Contains:
    * An ASIO context shared by all connected clients (10:20)
    * A single thread for the context. (10:25)
    * An `asio::acceptor` object to handle connections. (10:38)
    * A deck to store connected client `Connection` objects. (15:54)
    * An ID counter for assigning unique IDs to clients. (10:43)
    * A `queue_incoming_messages` (Threadsafe Queue of `OwnedMessage` objects) to hold received messages (10:08)
    * Key functions:
    * `Start()` (11:59): Creates a task to wait for connections and starts the ASIO context thread.
    * `Stop()` (13:08): Stops the ASIO context and joins the thread.
    * `WaitforClientConnection()` (13:32): An *asynchronous* task run by the ASIO context that waits for incoming connections using `asio::acceptor`.
    * `OnClientConnect()` (15:32): Called when a client attempts to connect, allowing the server to approve or deny it (customizable by the user).
    * `OnClientDisconnect()` (18:11): Called when a client disconnects.
    * `OnMessage()` (19:52): Called from within `Update()` (20:12) to handle messages in the incoming message queue (customizable by the user).
    * `Update()` (20:12): Processes messages from the incoming queue, calling `OnMessage()` for each. Users can control the number of messages processed per call to `Update()`.
    * `SendToClient()` (8:55): Sends a message to a specific client (using their ID).
    * `MessageAllClients()` (9:00): Sends a message to all connected clients (optionally excluding a specific client).
    *3. `Connection` Object* (24:14)
    * A template class representing a connection to a client (whether created by the server or by a client).
    * Includes:
    * An `owner` field (using `Owner` enum class) to distinguish between server-owned and client-owned connections. (24:26)
    * A socket (`sock`) (24:57)
    * References to the ASIO context and the relevant message queue (server's or client's) (24:45, 25:02).
    * A unique ID (`id`) if owned by a server. (25:54)
    * Key *asynchronous* tasks executed by ASIO:
    * `ReadHeader()` (27:54): Reads a message header from the socket.
    * `ReadBody()` (29:24): Reads a message body based on size indicated in the header.
    * `WriteHeader()` (31:30): Writes a message header to the socket.
    * `WriteBody()` (32:22): Writes a message body to the socket.
    * `AddToIncomingMessageQueue()` (30:16): Adds a completed message to the appropriate message queue, and re-primes the ASIO context to read the next header.
    * `Send()` (33:13): Called by either the server or client to send a message. Uses ASIO's `post()` to add a task to write the message to the socket (avoiding concurrent header/body writes).
    * `Disconnect()` (35:03): Uses ASIO's `post()` to add a task to close the socket cleanly.
    *4. `Client` Interface* (35:35)
    * Template class with most implementation already present from Part 1.
    * Uses an `asio::resolver` (36:25) to translate a domain name into an IP address/endpoint.
    * Key function: `Connect()` (35:59) now fully implemented. It resolves the host address, creates a `Connection` object (client-owned) (37:02), starts the ASIO context thread (37:29), and then calls `Connection::ConnectToServer()`.
    *5. Example: Ping Server and Broadcasting a Message* (38:37)
    * This part includes modifications to the client and server examples from Part 1 to showcase sending and receiving custom messages:
    * The client can now:
    * Send "Server Ping" messages with timestamps for calculating round-trip time.
    * Send a message to the server asking it to broadcast a message to all other clients.
    * The server responds accordingly, including:
    * Reflecting the "Server Ping" messages.
    * Receiving the broadcast request and distributing the message to all other clients.
    *Key Improvements:*
    * *Robust error handling:* Network failures and disconnections are detected and managed to prevent application crashes.
    * *Asynchronous design:* Network operations are handled by the ASIO context in a background thread, allowing the application logic to continue without blocking.
    * *User-friendly API:* Complexities of ASIO are hidden from the user, allowing for streamlined development of client and server applications.
    *Note:*
    While the framework is functional at this stage, it is still not ready for production as it lacks security and other necessary features. This is planned to be addressed in future videos.
    i used gemini 1.5 pro to summarize the youtube transcript

  • @catsoften
    @catsoften 4 роки тому +8

    2:20 As a beginner javascript programmer everything you say sounds massive. I can barely keep up, but I've learned so much from this series and your channel in general.

    • @codeman99-dev
      @codeman99-dev 4 роки тому +1

      May I suggest that you take some time to learn server/client patterns in node.js ?
      I promise you'll enjoy it and you'll avoid some of the confusing data types (namely the templates)

  • @sirgouki6207
    @sirgouki6207 4 роки тому +27

    For anyone getting an error on the std::scoped_lock usage along the lines of scoped_lock use of dependent type name must be prefixed with 'typename', you need to be using Visual Studio 2019, retarget the entire solution to the current version of the Windows SDK, and make sure every project is set to use C++17, not default, in their project settings.

    • @thehambone1454
      @thehambone1454 2 роки тому +1

      THANK YOU

    • @bloodfiredrake7259
      @bloodfiredrake7259 2 роки тому +1

      THANK THEE ME LORD

    • @kubacakagoomba
      @kubacakagoomba Рік тому

      Yeah, I've noticed that myself but then I got stuck again at 26:45 because VS2019 fails to compile the program. The error is: Error C2440 'initializing': cannot convert from 'net::tsqueue' to 'net::tsqueue &'

  • @Raging_Lemming
    @Raging_Lemming 4 роки тому +5

    I am super happy this got brought forward, this niche little series your doing is so helpful.
    Thanks for taking the time to make content like this.
    Your methods of explaining the material is spot on.

  • @oblivionronin
    @oblivionronin 4 роки тому +18

    "It's never gonna crash because you all write awesome code" Obviously OLC has never seen my github account lolll

  • @Howtheheckarehandleswit
    @Howtheheckarehandleswit Рік тому +1

    “Using a numeric id is much easier than using ip addresses” I mean, technically, IPv4 addresses *are* 32 bit integers, we just write them as 4 bytes converted to decimal

  • @Darkstar2342
    @Darkstar2342 4 роки тому +16

    34:30 Isn't there still a tiny race condition window, between checking if the queue is empty and re-scheduling the WriteHeader() call? What if the queue empties just after assigning bWritingMessage? Then the WriteHeader() call will not be scheduled and the message will just sit there, waiting...
    Since you don't need to split the sending part in Header/Body (since you know the complete message beforehand), wouldn't it be better to have a single "WriteMessage()" function that sends the whole message, avoiding the "header/body" interleave problem?

    • @costa_marco
      @costa_marco 4 роки тому +5

      Came here to say exactly that. Answering to you to get updates on this comment

    • @danbopes6699
      @danbopes6699 4 роки тому +14

      This wont happen because it's being run inside the asio context. We're posting a lambda to be run on that thread (asio context), and it won't process the work (Lambda we just passed) until the previous work (Any reads/writes) have been completed. Think of all the lambdas he's creating as blocks of code. At no point are 2 lambdas ever going to run at the same time.

    • @costa_marco
      @costa_marco 4 роки тому +2

      @@danbopes6699 I see. Thank you for the explanation. Threads and asynchronous calls are hard to wrap your head around.

    • @TylerDurden-id6yp
      @TylerDurden-id6yp 3 роки тому

      Just exactly what I was thinking. I am glad there is people paying attention to this wonderful videos.

    • @TylerDurden-id6yp
      @TylerDurden-id6yp 3 роки тому +1

      @@danbopes6699 Thanx a lot for the explanation. Now I am wondering if there is a reason to use thread-safe queues inside Asio context lambdas... 🤔 Maybe it is still necessary for those .front() calls that are made outside them.

  • @howardjohnprice
    @howardjohnprice 2 роки тому

    Great couple of videos. Thank you very much for making game network programming accessible. I like the way in video 1 the message size() returns the size of whole message (header+body) but in video 2 (implied by accompanying source) it mysteriously returns body size only. Forces the student following along to find and fix the problem!

  • @victordrouinviallard1700
    @victordrouinviallard1700 4 роки тому +4

    most of the time you should pass const& to shared pointers to avoid their copy when not necessary. Removes a lot of overhead, especially for an MMO ;)

  • @AustrianTutorialHD
    @AustrianTutorialHD 3 роки тому +4

    41:44 When I try to call Send() it tells me it isnt declared in this scope

  • @mateuscoutinhomarim9184
    @mateuscoutinhomarim9184 4 роки тому +3

    Man, your material is awesome, I'm lucky for starting to study networking in C++ just when you started this series. haha

  • @Willyzzy
    @Willyzzy 4 роки тому +3

    As someone who uses and has always used qt but would like to switch over to visual studio, I'd love to see a quick rundown video for the basics! Loving the network series also!

  • @lolowfi
    @lolowfi 4 роки тому +22

    Oh fun, client supplied buffer sizes. This MMO better be good otherwise someone might decide to send a few malicious headers with a MAX_INT size field. :)

    • @DanCojocaru2000
      @DanCojocaru2000 4 роки тому +27

      if (msg_size > 4096) { client.gtfo(); }

    • @OneMeanDragon
      @OneMeanDragon 4 роки тому +2

      @@DanCojocaru2000 or predefined lengths, if (msg_size > max_length_by_id(msg.id)) { client.lifetime_ban(); }, youll likely check if valid id and do the same thing aswell.

  • @jahoopyjaheepu497
    @jahoopyjaheepu497 4 роки тому +1

    Your explanations are always so clear, especially on this seldom discussed, yet very important topic.

  • @tudorradu5848
    @tudorradu5848 4 роки тому +4

    Thanks for this. Actually waited for this one.

  • @nikkiofthevalley
    @nikkiofthevalley 3 роки тому +8

    I spent 4 hours debugging why std::scoped_lock wasn't working, until I realized my project's C++ version was
    C++ 14, not 17.. *sigh*

    • @javidx9
      @javidx9  3 роки тому +1

      Lol, been there....

    • @NN-uy6ik
      @NN-uy6ik Рік тому

      Me too

    • @prgstev
      @prgstev Місяць тому

      when these things happen i decide to stop trying to "debug" it. Instead, I take a break and look at other alternative. Things that are not debuggable. Since I can't find any atm.

  • @Daggenthal
    @Daggenthal 4 роки тому +1

    Yeeeees, I've been eagerly waiting for the continuation of this series!

  • @soapdude4890
    @soapdude4890 Рік тому +1

    im grateful for your videos

  • @jean-naymar602
    @jean-naymar602 3 роки тому +2

    21:36
    He's gonna say Wireshark...
    He's gonna say Wireshark...
    It's comming...
    "A program called putty"
    Oh.

  • @adriancostin9138
    @adriancostin9138 4 роки тому +1

    so good seeing all of these concepts i learned about being put into practice. thank you

  • @jiifox3245
    @jiifox3245 3 роки тому

    This is just gold. So easy to understand this ASIO with javix.

  • @TeaShuty
    @TeaShuty 3 роки тому +6

    Hey javidx9! The first video of this series was recommended to me by one of my colleagues, because of the clear and easy-to-understand way you explain things. I got hooked up! I love programming and read/watch a lot of content, but I _rarely_ found anybody who can explain stuff as well as you. I also love the fact that you talk about design too while showing asio. It is so much more than a "tech tutorial", which is unfortunately all too common nowadays.
    A small question about the video. I noticed you use inheritance both for the client and server to implement the custom code (e.g. fire a bullet or ping). What do you think about the "composition over inheritance" principle? I read about it a few years ago, but to be honest, I never really understood the benefit of it. Your code seems very natural and simple with inheritance, so I don't see a reason to use composition instead. Would composition add anything to this example, in your opinion? Would you prefer composition in some other cases?

    • @javidx9
      @javidx9  3 роки тому +3

      Hey thanks TeaShuty :D My understanding of composition is that you can sort of inject functionality without worrying about hierarchy, but I guess the problem with this is it becomes syntactically messy (and I would guess, difficult to maintain?) In this series, there are have been several moments where I have felt inheritance is probably not required, and would prefer to have some bolt in functionality. I guess its a way of using OOP code and languages in a more procedural way? lol dunno, must confess, not a pattern I use much.

  • @alexo989
    @alexo989 4 роки тому

    very good presentation , as for asio itself (as demonstrated) - it is a perfect example on how to overcomplicate something relatively simple and make it hardly manageable/debuggable, I am not even talking about horrific buffer management

  • @kaiweiyeo4279
    @kaiweiyeo4279 2 роки тому +1

    From 22:40 onwards, you have to edit the entire source code and remove all the mistakes and typos. You have to go to the Github repository to check what you are missing.
    E.g. if (m_threadContext.joinable) //WRONG
    if (m_threadContext.joinable()) //CORRECT
    E.g. TsQueue m_qMessageIn;
    TsQueue m_qMessagesIn; //Beware the additional 's'. It will be added in the new project source file.

  • @DM-qm5sc
    @DM-qm5sc 4 роки тому +5

    Great video as always!!!!

  • @thebarondisco7741
    @thebarondisco7741 4 роки тому

    I don't code in C at the moment, but all these videos show a lot of concepts that easily translate to all programming efforts. Really enjoy it.

  • @0megaSapphire
    @0megaSapphire 2 роки тому +1

    "and all of the other chrono rubbish you have to do to display this number". This made me laugh :D

  • @user-mh9rh4me3m
    @user-mh9rh4me3m 4 роки тому +3

    Thank you so much! :) Was dreaming about such content !!!

  • @lucadavidian5441
    @lucadavidian5441 4 роки тому +2

    Trying to implement this framework myself, following along the great explanation from Javid, whenever I'm stuck I have Doc's voice in my head repeating: "you're not thinking asynchronously!!"

  • @BossBeneBaby
    @BossBeneBaby 2 роки тому +2

    For Linux dont forget to link the thread library otherwise it won't build.

  • @krytharn
    @krytharn 4 роки тому +1

    Outstanding tutorial! Looking forward to part 3. One thing I'd like to learn more about is on finding the server's IP on the local network using a broadcast message. Is that something you can incorporate as well?

  • @proupin7258
    @proupin7258 3 роки тому

    He wasn't kidding when he said networking is complex GODDAMN!!

  • @sirgouki6207
    @sirgouki6207 4 роки тому +3

    Also, if anyone is getting an error that Send is not defined in the client, use m_connection->Send(msg); instead.

  • @kennythegamer1
    @kennythegamer1 4 роки тому +2

    Instead of having dedicated server and client classes, you could just have one class for the "net_node" by removing the restriction of clients only being able to have one connection. It would allow the framework to be more flexible and allow meshes and other structures of nets while reducing the size of the framework at the same time.

  • @herrdingenz6295
    @herrdingenz6295 2 роки тому

    10:10 why would we need to pass the connection/client shared pointer to the OnMessage function if the only messages the server will ever receive are of type 'owned_message' which already include the connection/client pointer?

  • @dandymcgee
    @dandymcgee 3 роки тому

    Why are lines 63 and 64 at 34:57 not a race condition? Is it because it's wrapped in an asio::post and that is somehow atomic for our use-case?

  • @RogueShadowTCN
    @RogueShadowTCN 4 роки тому +2

    This is incredible. I'm gonna need a long weekend to try this stuff....

  • @arbitervildred8999
    @arbitervildred8999 2 роки тому +2

    well i already have PuTTY :) + don't we need some sort of deltatime or fps in order to not kill the processor with 100000 while loops per second? also each client will move at the speed of each machine
    22:00 for anyone who forgot the setup of project
    right click > Properties > VC++ Directories >> Include Directories >> add "../NetCommon" and asio \include path
    right click > Build Depencencies... > Project Dependencies... >> check NetCommon box
    and don't forget the "#include "olc_net.h>" in server file
    also olc_net.h should contain this now
    #pragma once
    #include "net_common.h"
    #include "net_message.h"
    #include "net_client.h"
    #include "net_server.h"

  • @PetrPss
    @PetrPss 4 роки тому +1

    I know, it's unfinished, but:
    1. connection::Send(): Between lines 'bool bWritingMessage = !m_qMessagesOut.empty();
    ' and 'm_qMessagesOut.push_back(msg);' queue can get empty. It doesn't matter now, when all access to m_qMessagesOut is done via 1 thread (asio context run). But still, it may become thread-(un)safe problem in the future.
    2. tsqueue::wait(): 'cvBlocking.notify_one' can finish before 'cvBlocking.wait' starts => infinite waiting. You should use same mutex for queue and for condition variable. OR move all 'std::unique_lock ul(muxBlocking);' at the top of the functions where it occurs.

  • @slartibartfastBB
    @slartibartfastBB 4 роки тому +2

    For Mac users who don't have PuTTY, use ssh instead to test the server, give it an address and port
    $ ssh 127.0.0.1 -p 60000

  • @onuberonly7846
    @onuberonly7846 4 роки тому +3

    I am learning more here than my university network programming class

  • @jandeboer-u9y
    @jandeboer-u9y Рік тому +1

    I ran into this interesting problem with your networking code: 'pinging' the server takes about 0.5 ms on my system when triggered the first time. About 40 ms each time thereafter. Until 'messageAll' is invoked, then the first time thereafter we are back in the 0.5 ms zone. This behavior is consistent here. Anyone else ran into this? Any suggestions?

  • @platinoob__2495
    @platinoob__2495 3 роки тому +1

    on 26:50, how do you get "Connection Approved", how does "OnClientConnect(newconn)" returns "true" since:
    virtual bool OnClientConnect(std::shared_ptr client)
    {
    return false;
    }

    • @javidx9
      @javidx9  3 роки тому

      Polymorphism overrides that base method.

    • @platinoob__2495
      @platinoob__2495 3 роки тому

      @@javidx9 Hi, thank you for all the help until now and sorry to bother you again, but, in "ReadHeader()' (as it is in 39:08), "asio::async_read()" doesn't get called, I even went to "asio::async_read()"'s definition and changed it a bit, so the first thing to do is print a message to the screen (I just added a "std::cout", I deleted it later), but that message was never printed, actually, later by accident, it got printed, but by NetClient.exe, it does so every time I close NetServer.exe before NetClient.exe
      Thank you again

  • @kubacakagoomba
    @kubacakagoomba Рік тому

    I'm stuck at this part 26:45 because VS2019 fails to compile the program. The error is: Error C2440 'initializing': cannot convert from 'net::tsqueue' to 'net::tsqueue &'
    I've already switched from C++14 to C++17 because that also caused issues with compilation previously.

    • @kubacakagoomba
      @kubacakagoomba Рік тому +1

      Ended up copying and pasting the code from Github and it compiled succesfully. Not sure what that compilation error was about because I'm sure up to that point I was following the tutorials and doing things step by step :/
      I will still continue watching them though!

  • @jassskmaster7575
    @jassskmaster7575 3 роки тому +1

    For some reason my client can send messages and the server receives them, but the Server.cpp's 'OnMessage' function is not being called when a new message comes in. I have confirmed the server is indeed receiving the message, but just that function won't call. I've basically copy pasted the entire project files and it still doesn't work

  • @magisteriumemporium1411
    @magisteriumemporium1411 4 роки тому +1

    Thank you Mr. Bearded Man.

  • @bartff5568
    @bartff5568 4 роки тому +6

    You should have a full c++ series, you're great :)

    • @clonkex
      @clonkex 4 роки тому

      Series is singular as well. 1 series, 2 series.

    • @bartff5568
      @bartff5568 4 роки тому

      @@clonkex Thanks,

  • @ClaytonMalarkey
    @ClaytonMalarkey 3 роки тому

    I am really enjoying this series

  • @herrdingenz6295
    @herrdingenz6295 2 роки тому

    34:50 this code is so confusing .. why not simply just write:
    {
    bool queueIsEmpty = m_qMessagesOut.empty();
    m_qMessagesOut.push_back(msg);
    if(queueIsEmpty)
    {
    WriteHeader();
    }
    }
    is that double negation necessary?!? i think not so

  • @mishabender1611
    @mishabender1611 4 роки тому +1

    Thank you so much for this detailed comprehensive explanation! Are you going to create beast server/client lessons as well?

  • @michaelmahn4373
    @michaelmahn4373 4 роки тому +3

    41:00 'auto' is your friend ;)

    • @codeman99-dev
      @codeman99-dev 4 роки тому +2

      I have to disagree. I limit the usage of auto for temporary things (start and end in the same scope) that also have a near meaningless type. Stuff like trying to definite an iterator.
      C++ being strongly typed, I would prefer to see the datatype if it has any meaning at all. It does in this case.

    • @wizardy6267
      @wizardy6267 4 роки тому

      auto is pretty when you do not need to care what is the variable type. Or you tired of using template ~

  • @turpialito
    @turpialito 4 роки тому

    Been waiting for this one. Judging from the comments, there are a few of us curious: is this the same ASIO that drives audio and MIDI interfaces? That particular ASIO has a lot of network capabilities, extensible though other protocols. Thanks and cheers, mate.

  • @sniperisaac1268
    @sniperisaac1268 4 роки тому +1

    More More More More !!!!!!!!!!!!!!!!!!!!!!

  • @tomson8550
    @tomson8550 3 роки тому

    I don't understand why server_interface has no Send function, and instead call Send function of that client to send message to that client?

  • @platinoob__2495
    @platinoob__2495 3 роки тому

    Visual Studio 2019 only makes .exe from NetClient and not from NetServer as well, so when I run it, like in 22:56, it runs NetClient.exe, what can I do about it?

    • @javidx9
      @javidx9  3 роки тому +2

      You can only run one at a time from within VS, that's why I launch them manually from the project folder.

  • @giorgioguglielmone6528
    @giorgioguglielmone6528 Рік тому

    Could you tell me how to pass the open socket as a parameter to a C++ function ?

  • @howardjohnprice
    @howardjohnprice 2 роки тому

    I have noticed that connection::IsConnected returns true as soon as connection::ConnectToServer is called. It seems to be because m_socket is set to open inside the call to asio::async_connect but before the handler is called. This means that the client thinks it is connected, even if the endpoint is invalid.

  • @marcofe82
    @marcofe82 4 роки тому +1

    Thank you so much for your videos!Really interesting!

  • @tu70_nguyeninh83
    @tu70_nguyeninh83 Рік тому

    i want to learn there , so what book i should learn ?
    thank for helping me

  • @Ownage4lif31
    @Ownage4lif31 4 роки тому +4

    You make this look so easy lol. I've made some c style server clients, but never this abstract. Pretty neat ngl, very good info to learn here!

    • @javidx9
      @javidx9  4 роки тому +5

      Thanks, though dont be fooled by the magic of video editing! It is complicated stuff, that takes practice and patience to develop 😁

    • @Ownage4lif31
      @Ownage4lif31 4 роки тому +3

      javidx9 still though, all that in depth explanation and time you've put into it. I can see you like to really let people understand things! I can't wait for the rest, as this is actually really good knowledge.

  • @PoorSkill
    @PoorSkill 4 роки тому +2

    Ohh suprise video 👍👍👍

  • @Marci124
    @Marci124 4 роки тому +7

    "...using a tool that most network developers love and depend on"
    ...netcat?
    "putty"
    I didn't expect that somehow, to me it was always just windows ssh for uni connections.

    • @dascandy
      @dascandy 4 роки тому

      I was also surprised. It's like "Telnet? Curl? Wget? Netcat?" and then he says Putty.

    • @wizardy6267
      @wizardy6267 4 роки тому

      I use putty to send data to develop board serial port. Don't know putty can do network things :p

    • @jmcc000
      @jmcc000 4 роки тому +1

      @@wizardy6267 It's great for managing Linux computers remotely.

  • @kaiweiyeo4279
    @kaiweiyeo4279 2 роки тому +1

    I assumed we had to setup the Netserver Project as a .exe instead of a static library .lib. As a static library, it will run into problems.

  • @pitue_
    @pitue_ 3 роки тому

    Since STL containers aren't thread safe, wouldn't using a std::deque for the connections be dangerous? The async_accept handler gets called from a different thread and writes to the deque.

    • @thjo1964
      @thjo1964 3 роки тому

      adding one more question here: Is tsqueue really thread safe? I think data race can happen between tsqueue.empty() check and tsqueue.pop() operation

  • @LogicHiveMind
    @LogicHiveMind 4 роки тому +2

    Thanks a lot for this stuff

  • @versatran01
    @versatran01 4 роки тому

    I saw a lot of shared_ptr passed to function by value, could it be better to just pass in by const ref?

  • @thjo1964
    @thjo1964 3 роки тому

    @javidx9
    Thank you for good quality video, I'm new to asio and am learning a lot from this. just one curious thing:
    Could you explain the reason behind choosing deque for container of connections? The erasing/removing unvalidated clients over whole deque seems to be worst O(n^2) time complexity. I'm wondering if unordered_map or linked_list would do better.

  • @gilgamesharcher8449
    @gilgamesharcher8449 Рік тому

    Why is the latency so big from sendign 8 bytes it takes 0.7 ms on the same computer

  • @vilkillian
    @vilkillian 4 роки тому +3

    17:50
    what if client is nullptr (or anything else signaling that client == false)
    you just proceed do stuff related to client object which could be disposed. That might become a problem i suppose.
    i would have written like this:
    if(client && client->isConnected()) { ... }
    else if (client) { OnClientDisconnect(client) client.reset(); }
    this will ensure that client object is not null and you can call methods in that instance.
    and by the way, why are calling reset using dot and not arrow? i thought 'client' is a pointer, shared, but nonetheless a pointer

    • @vilkillian
      @vilkillian 4 роки тому

      @@MuhammadHosny0 whats wrong?

    • @michaelmahn4373
      @michaelmahn4373 4 роки тому +1

      reset() is a method of the class shared_ptr. You only use the arrow operator if you call methods of the stored class.

    • @vilkillian
      @vilkillian 4 роки тому

      @@michaelmahn4373 still, if this object is empty i.e. if there is no instance, there is nothing to call

    • @michaelmahn4373
      @michaelmahn4373 4 роки тому

      @@vilkillian I was only answering the second question, why he uses dot instead of ->

    • @PetrPss
      @PetrPss 4 роки тому +1

      @@vilkillian shared_ptr object (client) still exists. And has reset() method. But it could hold pointer to object of connection class. Or it could hold nullptr. And I agree, 'if (client)' should be top-level 'if' there.

  • @brianmac8260
    @brianmac8260 4 роки тому

    So now the Console Game Engine will run on the Server? Yayyy.

  • @ayush.kumar.13907
    @ayush.kumar.13907 3 роки тому

    hey, i coded this project and everything is working fine, but when i test server-client communication with multiple client like at the end of the video and press 3 to quit client, all the opened client consoles close simultaneously, no matter which one was in focus. Anyone have any idea why this is happening?

  • @conman698
    @conman698 4 роки тому +20

    I don't know how your head isn't pulsating with all that knowledge trapped in there. Maybe you use UA-cam as a dumping ground to prevent outright combustion?
    Joking aside thanks for the video!

  • @jiifox3245
    @jiifox3245 3 роки тому

    In ReadBody(), would it be better to use async_read_some() intead of async_read()? Because if the the body is huge, isn't it better to read it in smaller junks? I think you did this in the first video when reading the html data... you used async_read_some there. If async_read() meant to be used if the body-data is small in size?

    • @javidx9
      @javidx9  3 роки тому +1

      It's not really about body size, it's about knowing in advance how much data you wish to read. Streamed data like webpages you just nibble at until no more data arrives or it signals termination. In a packet system, there are no unknowns, so I request of asio to not bother me again until all the data I need is ready.

    • @jiifox3245
      @jiifox3245 3 роки тому

      @@javidx9 Yes async_read() makes "life easier" if just needs all the data/body at once. Ok, async_read_some() gives more control. Like if I want a system receiving huge files and able to for example pause the file-send and then resume.... in that kind of system I guess async_read_some() would be good, am I right?
      I did that kind of programming before with MFC CAsyncSocket ... so splitting a huge file data and building the big body message by its parts at the receiving end. So each body part has its index so the receiver can re-assemble the message.

    • @javidx9
      @javidx9  3 роки тому

      Yeah, if you need to interrupt the transfer reliably then nibbling away at it is your only option.

  • @nissanGold
    @nissanGold 4 роки тому

    Big thumbs up👍. Great Tutorial like always, can't wait for the security patching.

  • @BossBeneBaby
    @BossBeneBaby 2 роки тому

    Hello, wenn using this code i get quite high ping times when sending inside my local network. For example when i run the server on my windows laptop and use my linux pc as a client i get ping times between 50ms and 100ms. This seems quite a lot for sending a message such a short distance. Any ideas why this is? If both the client and server run on the same machine i get under 1ms ping times.

  • @genesis5468
    @genesis5468 4 роки тому +1

    Been binging your videos lately because i want to get into C++, and loving them so far! is there a place for me to get some basics? Like making the game screens and such and how they work, i have been looking into making some atari games to start out and theres jist so much info everywhere its a bit overwhelming haha. Thanks for these vids and im looking forward to more!

    • @wizardy6267
      @wizardy6267 4 роки тому +1

      Sounds like you are looking for OpenGL/SDL tutorial, there are UA-camrs talking about using OpenGL making game engining he also has a list video talking about c++ basics.

  • @jonohiggs
    @jonohiggs 4 роки тому +1

    the connection owner feels like a slightly strange way of doing this... similar objects with some slight changes depending on what it is feel like you want ClientConnection and ServerConnection subclasses

  • @Dygear
    @Dygear 4 роки тому

    Thank you for this. I can't wait for Part 3 now! I'm going to have to watch this video and the first video again. I'll see if I can figure out the memory leak myself as a technical exercise. The 100% Proc usage is interesting. Have to understand the context of all of the function calls to really figure out what is going on there. That should be fun also.

  • @doctorproctor8702
    @doctorproctor8702 4 роки тому +1

    Hi 👋, awesome vids, any tips for struggling software engineer

  • @giuliograziani3261
    @giuliograziani3261 2 місяці тому +1

    thanks so much!

  • @everythingisnothing7588
    @everythingisnothing7588 2 роки тому

    Can you make a UDEMY course about c++?

  • @artemisftwable
    @artemisftwable 2 роки тому +1

    While this is a good video to learn some basic networking concepts and their implementations, it has basic design flaws like using a tcp socket. Online games almost always use udp for gameplay, and most of those are custom "reliable" udp. Just a heads up, good video regardless.

  • @himelsarkar137
    @himelsarkar137 4 роки тому

    Sir is there any way that can automated broutforceing all the port's, protocol's all the netwark machine at a time .auto magically download word list from net . Spacially GPU based 🔥 working process

  • @diabolicalscientist
    @diabolicalscientist 3 роки тому

    Thank you for the video. This helped me very much.

  • @GuNStaRia
    @GuNStaRia 2 роки тому

    If anybody has problems with ping. fix net_message.h line "return sizeof(message_header) + body.size();" to "return body.size();" int size() method. 30:00 in Part #1
    I had the same problem and could fix this only with comparing with guthub.

  • @focuseletronica
    @focuseletronica 4 роки тому +1

    Esse cara Sabe Muito!!

  •  4 роки тому

    Great video, a useless comment, though: funny, that black text cursor always makes me think there is a bug (literally, not software bug ...) on my monitor ;)

  • @Volian0
    @Volian0 4 роки тому +2

    Yees

  • @fengwang6783
    @fengwang6783 4 роки тому

    Thank you OLC!