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.