Advertisement

how to comunicate with diffrent exe files?

Started by March 19, 2015 12:23 AM
12 comments, last by hplus0603 9 years, 8 months ago
Wait, is this based off of my suggestion in your other forum post ( http://www.gamedev.net/topic/666672-systemnetsocketsoverlappedasyncresult/ ) where I said this?

I highly recommend separating your receive code from your data handling code;


I didn't mean you should make a separate EXE. I meant that your function was doing too many different kinds of tasks (socket receive, SQL queries, etc) all in one function.

I normally have a single BeginReceive/EndReceive loop to read data from the socket, which splits the data up into messages. The messages are then routed to different functions (in the same EXE). This makes it easier to add more functionality later without having to write several BeginReceive/EndReceive pairs each time (and worrying about accidentally starting a second BeginReceive on the same socket at the wrong time).

I was under the impression in that thread that this was a WinForms server EXE (which is fine for debugging purposes, I'm not sure why Sean's brain died). I have no idea why you would need a third process in addition to your Unity game and your Server, though.


In your Unity game, even if you don't need to send/receive data every frame, you can still have your socket code work the same basic way without too much overhead. Here's what I do in Unity (you'll have to excuse any typos I make here since I'm freestyling this):


public class UnityTcpComponent : MonoBehaviour
{
    // (these are wrapper classes on WP8/Metro that function the same way)
    TcpClient tcpClient;
    NetworkStream stream;
    
    IAsyncResult arConnect;
    IAsyncResult arReceive;
    byte[] recvBuffer = new byte[2048];

    // TODO: There would be some event/callback/dispatcher member here that can be configured to pass received data to whatever other code you're using this instance for.

    public void Connect(string hostname, int port)
    {
        tcpClient = new TcpClient(...);
        arConnect = tcpClient.BeginConnect(..., null);
    }    

    void Update()
    {
        if (arConnect != null && arConnect.IsComplete)
        {
            tcpClient.EndConnect(arConnect); // end completed connect operation.
            arConnect = null; // don't accidentally handle it again.
            stream = tcpClient.GetStream(); // get the stream to read from.
            arReceive = stream.BeginReceive(recvBuffer, 0, 2048, null); // begin read operation immediately.
        }

        while (arReceive != null && arReceive.IsComplete) // while loop allows fast receipt when there is more than one buffer of data available per frame.
        {
            int bytesRead = stream.EndReceive(arReceive); // end completed read operation.

            // TODO: accumulate the received data and handle it if there are one or more complete messages received.

            arReceive = stream.BeginReceive(recvBuffer, 0, 2048, null);  // begin another read operation.
        }
    }
}
Of course there's a bunch of exception handling in the real code as well, but that's the basic idea. The reason I'm using Begin/End is that my code needs to be used on WP8 and Metro, which have slightly different versions of the socket library which don't support the select-and-recv pattern that you'd normally use if you were polling on a single thread (because MSFT decided in their infinite wisdom that nobody would ever want to care about which thread their code was running on anymore so they got rid of most of the blocking-oriented methods). The reason I don't use the callbacks in the Begin* methods is because Unity is a little b**** about making pretty much ANY UnityEngine.dll calls from background threads, so pretty much everything needs to happen in its Update methods - it's more wasteful in Unity to use the callbacks AND a concurrent queue to message-pass back to the Unity thread than it is to poll every frame.


I didn't mean you should make a separate EXE

well. thank you my friend. and i understood your answer. this is for compeletly different part

Advertisement

Moving to Multiplayer & Networking Programming.

(That’s what I would have said if I were a moderator.)

L. Spiro

I'm pretty sure you wrote it even if you aren't a moderator.

And in an effort to stay on track...

There are many different ways for processes to communicate.

On a single machine you can use various types of pipes, shared memory, OS signals, and OS-provided message queues, plus all the methods listed after.

Within a single network you can use shard files or other shared network resources, specialized network message passing architectures, and the one listed below.

Finally you get the near universal solution: Network sockets. You can use them on a single computer, on a local network, or across the global internet.


server is winform ... the game uses c# .net sockets.

That's somewhat reasonable for a starting point. It is something you have today and it will mostly work okay on the small scale. You can replace out the server with a more dedicated, non-GUI program when you reach the point where that makes sense to you.

You might also look into existing libraries that provide support for added functionality. There are many wonderful code collections (free and paid) that punch through NATs and uPNP home routers, that build interconnectivity meshes allowing routing of traffic even between peers that aren't directly connected to each other, provide both reliable (potentially slow) and unreliable (potentially losing data) networking channels.

Some even throw in support for features like VoIP that satisfies government requirements of permitting government spying.

If the "game server" runs the same simulation as "game clients," all written in Unity, then perhaps a better architecture would be one where the clients connect to the Unity-based server, and the Unity-based server in turn uses your other program as a back-end server -- a form of three-tier architecture, where your Unity-based game server is the "application server."

You can connect from that Unity server to another program running on the same machine by simply listening on a known TCP port (such as 12345) and having the Unity game server connect to localhost:12345 using regular sockets. Or, if the operations you do are batch-like, perhaps use HTTP, even though it's just local traffic.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement