“Using Sockets” is like saying “using networking.” Sockets is a network programming API, it's not a particular technology.
What protocol are you using with the sockets? TCP? UDP? Something higher-level, like HTTP, RTP, gRPC, DTLS, QUIC, or Websockets?
What is your game? Is it turn based, like chess? Is it action oriented, like a first person shooter? Does it use deterministic simulation, like an RTS? Does it have thousands of players, like an MMORPG?
If we knew more, we could probably give a better answer.
That being said – it sounds like your question is about “marshaling,” not about “networking.” “Marshaling” concerns how you pack and unpack your applications state into network packets (or other flat buffers, such as files, for savegames and such.) There's also probably a question about messaging structure in there?
Currently, it sounds like you're already using RPC – the client sends a RPC to the server, which does some processing, and sends a response. This is a (synchronous) procedure call. It also sounds like perhaps the server cannot initiate a call to the client? If so, the client would have to issue a “poll” command to hear about updates to the shared game state, which is generally very inefficient for real-time games, but can work OK for “base defense” or “farming” or “turn based” kinds of games.
What might be confusing here, is that many RPC packages come with their own “preferred” marshaling implementations. gRPC comes ,with Protocol Buffers, Unix-RPC comes with XDR Java Remoting comes with Java Serialization, and so on. But the marshaling is actually separate from the networking – you can use marshaling just for savefiles (like serialization in MFC) and you can use networking libraries with just blobs-of-binary-data (such as RakNet or ENet.)
So, without knowing more about what your gameplay is, and what your goal is, it's not really possible to give good recommendations. If your game is real-time-ish, the “general idea” is that each client sends a stream of events to the server, and the server sends a stream of events to the client, but those aren't necessarily tightly coupled in a request/response manner. If the client fires the gun, it sends the “client fired the gun” message to the server, and if someone gets hit on the server, the server sends the “someone got hit” message to the client. This way, it matters less “who” did it, and it matters more what the “outcome” is, which is why you have a server – to break ties and order events across multiple distributed players. Typically, games will do this using some form of binary serialization, on top of UDP. Each UDP packet starts with some framing information (clock information, sequence information, client identity, received other-way traffic informatino, crypto framing) and then there's a list of messages. Each message has a type, and a length, and the receiving side dispatches the message based on the type ID (typically using some table of function pointers, or hash table of reactor objects, or something like that.) Some timer will collect messages emitted by the game, and schedule them to be sent on some schedule, all packed into one datagram, for efficiency.
If you have more specific questions about the problem you're facing, perhaps you can share more details (without posting hundreds of lines of code, which really isn't helpful :-) ) and perhaps you can get a more detailed answer!