I've added the code to both below. It may be a little messy because I've been trying anything I could possibly thing of to get it to work. Here's the full code for both the server and the client.
Server:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Threading;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace GameServer
{
class SocketClass
{
public Socket accepted;
public Vector2 position;
Vector2 lastPos;
public int id;
public SocketClass(Socket sock, int num)
{
accepted = sock;
position = Vector2.Zero;
lastPos = Vector2.Zero;
id = num;
}
public void recData()
{
Thread receiveThread = new Thread(() =>
{
while (true)
{
try
{
byte[] buffer = new byte[500];
int size = accepted.Receive(buffer);
Array.Resize(ref buffer, size);
MemoryStream ms = new MemoryStream(buffer);
BinaryFormatter bf = new BinaryFormatter();
lastPos = position;
position = (Vector2)bf.Deserialize(ms);
Console.Write(id + ": " + "X: " + position.X + " Y: " + position.Y + "\r\n");
}
catch
{
}
}
});
receiveThread.Start();
}
public bool positionChanged()
{
if (lastPos == position)
{
return false;
}
else
return true;
}
public Vector2 getPos()
{
return position;
}
}
class Program
{
static void Main(string[] args)
{
int nextId = 0;
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
List<SocketClass> incoming = new List<SocketClass>();
sock.Bind(new IPEndPoint(0, 1234));
sock.Listen(0);
Thread accept = new Thread(() =>
{
while (true)
{
incoming.Add(new SocketClass(sock.Accept(), nextId));
Console.Write("Connected\r\n");
try
{
incoming[nextId].recData();
}
catch
{
}
nextId++;
}
});
accept.Start();
while (true)
{
for(int i = 0; i < incoming.Count; i++)
{
if (incoming.positionChanged())
{
for (int j = 0; j < incoming.Count; j++)
{
if (incoming.id != j)
{
try
{
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, incoming.position);
incoming[j].accepted.Send(ms.ToArray());
}
catch
{
}
}
}
}
}
}
Console.Read();
}
}
}
And here's what I'm using for the client:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Threading;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace TestGame
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Socket sock;
Texture2D ball, otherBall;
Vector2 otherVector;
Vector2 position;
Vector2 lastPos;
Thread sockThread;
int connectedPeople;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
position = new Vector2(50, 50);
lastPos = Vector2.Zero;
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
ball = Content.Load<Texture2D>("testpic");
otherBall = Content.Load<Texture2D>("othertest");
try
{
sock.Connect("127.0.0.1", 1234);
BinaryFormatter bf = new BinaryFormatter();
sockThread = new Thread(() =>
{
byte[] buffer = new byte[900];
while (true)
{
int size = sock.Receive(buffer);
connectedPeople = 1;
Array.Resize(ref buffer, size);
MemoryStream ms = new MemoryStream(buffer);
try
{
otherVector = (Vector2)bf.Deserialize(ms);
}
catch
{
}
}
});
sockThread.Start();
}
catch
{
}
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
KeyboardState keystate = Keyboard.GetState();
if(keystate.IsKeyDown(Keys.A))
{
position.X -= 1;
}
if (keystate.IsKeyDown(Keys.D))
{
position.X += 1;
}
if (keystate.IsKeyDown(Keys.W))
{
position.Y -= 1;
}
if (keystate.IsKeyDown(Keys.S))
{
position.Y += 1;
}
if (lastPos != position)
{
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, position);
byte[] buffer = ms.ToArray();
sock.Send(buffer);
}
lastPos = position;
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.Draw(ball, position, Color.White);
if (connectedPeople >= 1)
{
spriteBatch.Draw(otherBall, otherVector, Color.White);
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}