I have been doing several hours of research on a topic that I thought would've been very trivial. So far I've come up empty handed and wanted to see what you guys think. I'm currently messing with XNA (which is actually quite irrelevant now that I think about it) building a client/server architecture for a "game" project. Really nothing more than playing around with networking, animations, etc.
Anyway I've read quite a bit about the differences between Synchronous and Asynchronous networks and the viability of threading synchronous applications to simulate asynchronous behavior and have decided to do just that. Now I know my code isn't pretty but I'm just testing right now. Here's how it's (sort of) set up:
Game is run in the main thread. On initialization->Connect to server. Send x position of player class's sprite object to server. Server receives, acknowledges with a print to console and sends the same data back. Data is read into a logfile.
I've begun work on a messenger class that will eventually read (or sniff) the packets coming from the server and dispatch them accordingly making draw/update calls as needed. My problem is that I cant figure out how to properly thread the connection method to have that run (and then block?) separate from the Send/Receive loop (or what I'd like to be a continuous loop).
Like I said I'm no expert, I'm just doing this for fun so I may be all over the place. Anyway here are the essentials code-wise:
Networking.cs
using System;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
namespace DrawTest
{
class Networking
{
public void StartClient(Messenger m)
{
// Data buffer for incoming data.
StreamWriter _con = new StreamWriter("data.txt");
// Connect to a remote device.
try {
// Establish the remote endpoint for the socket.
// This example uses port 11000 on the local computer.
IPHostEntry ipHostInfo = Dns.Resolve("127.0.0.1");
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress,3000);
// Create a TCP/IP socket.
Socket sender = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );
// Connect the socket to the remote endpoint. Catch any errors.
try {
sender.Connect(remoteEP);
_con.WriteLine("Socket connected to {0}",
sender.RemoteEndPoint.ToString());
while (m.isAlive)
{
m.SocketStream(sender, _con);
}
if (Messenger.mPacket() == "close_socket")
{
_con.WriteLine("Connection closed by client.");
sender.Shutdown(SocketShutdown.Both);
sender.Close();
}
} catch (ArgumentNullException ane) {
_con.WriteLine("ArgumentNullException : {0}",ane.ToString());
} catch (SocketException se) {
_con.WriteLine("SocketException : {0}",se.ToString());
} catch (Exception e) {
_con.WriteLine("Unexpected exception : {0}", e.ToString());
}
_con.Flush();
}
catch (Exception e) {
_con.WriteLine(e.ToString());
_con.Flush();
}
}
}
}
Messenger.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
namespace DrawTest
{
public class Messenger
{
byte[] bytes = new byte[1024];
byte[] incBuffer = new byte[1024];
public bool isAlive = true;
Vector2 position = new Vector2(0.0f, 0.0f);
public Vector2 getPos()
{
return position;
}
public void setPos(Vector2 pos)
{
position = pos;
}
public void SocketStream(Socket s, StreamWriter logfile)
{
byte[] msg = null;
int bytesSent = 0;
int bytesRec = 0;
msg = BitConverter.GetBytes(position.X);
// Encode the data string into a byte array.
bytesSent = s.Send(msg);
// Receive the response from the remote device.
bytesRec = s.Receive(incBuffer);
//logfile.WriteLine(Messenger.mDecoder(incBuffer, bytesRec));
}
public string mDecoder(byte[] msg, int size)
{
string DecodedMessage;
byte[] bytes = new byte[1024];
DecodedMessage = Encoding.ASCII.GetString(msg, 0, size);
if (DecodedMessage == "close_socket")
{
isAlive = false;
return DecodedMessage;
}
return DecodedMessage;
}
public static string mPacket()
{
return null;
}
}
}
Think that should do it. The other code is relatively self-explanatory (abstract player/sprite classes and the typical XNA Game.cs)
Thanks in advance for any help!