UDP SocketAsyncEventArgs mismatching data sent and received by server and client - c#

I'm trying to learn Game Networking programming so I started a very simple async udp socket system using Unity, however when I added JSON serialization things got a little bit weird.
I can connect to the server and send packets with the SendPacket(string msg) method and it will receive it fine on the server side. And it will work fine as long as the size of the msg variable is the same size or bigger. So if I send a string "Hello" and then one "Hello World" will work fine and be able to print it on the other size. However if I was now to send another packet with the string "Hi" nothing would happen and no more connections will work on that socket neither sending new packets.
I have checked and I'm receiving the packet over the network and it's not empty it has the information however it seems to stop when it gets to the code:
Packet p = e.Buffer.FromJsonBinary<Packet>();
Which is on the OnConnect function on my server side.After that function It seems my server stops listening not accepting new connections and no other packets will be receive, I suspect it somehow stops my async process.
For the Json Serialization I'm using JsonUtility from Unity.
Any ideas what is happening?
Server Class
public class Server
{
private static string _protocolID = "hash";
private static ushort _port = 11000;
private Socket _socket;
private SocketAsyncEventArgs _event;
private List<Socket> _connections = new List<Socket>();
public void Start()
{
Listen();
}
private bool Listen()
{
// Create UDP Socket
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
// Set the socket into non-blocking mode
_socket.Blocking = false;
try
{
_socket.Bind(new IPEndPoint(IPAddress.Any, _port));
_event = new SocketAsyncEventArgs();
_event.Completed += OnConnect;
byte[] buffer = new byte[1024];
_event.SetBuffer(buffer, 0, 1024);
//_socket.ReceiveAsync(_event);
StartListening(_event);
}
catch (Exception e)
{
Debug.LogException(e);
return false;
}
return true;
}
private void StartListening(SocketAsyncEventArgs e)
{
//e.AcceptSocket = null;
_socket.ReceiveAsync(e);
}
private void OnConnect(object sender, SocketAsyncEventArgs e)
{
if (e.BytesTransferred > 0)
{
if (e.SocketError != SocketError.Success)
Debug.Log("ERROR"); // TODO: Close Socket
Packet p = e.Buffer.FromJsonBinary<Packet>();
if (p._protocolID != _protocolID)
Debug.Log("Protocol Error");
Debug.Log("Connect:" + p._msg);
if (!_socket.ReceiveAsync(e))
{
// Call completed synchonously
StartListening(e);
}
}
else
{
Debug.Log("No data");
}
}
}
Client Class
public class Client
{
private static string _protocolID = "hash";
private ushort _port = 11000;
private string _ip = "127.0.0.1";
private Socket _socket;
private SocketAsyncEventArgs _event;
public bool Connect()
{
// Create UDP Socket
_socket = new Socket(SocketType.Dgram, ProtocolType.Udp);
// Set the socket into non-blocking mode
_socket.Blocking = false;
IPEndPoint ip = new IPEndPoint(IPAddress.Parse(_ip), _port);
_event = new SocketAsyncEventArgs();
//_event.Completed += Callback;
try
{
_socket.Connect(ip);
Debug.Log($"Connection was to {_ip} was sucessfull");
}
catch(Exception e)
{
Debug.LogException(e);
Debug.Log("Couldn't connect Socket");
return false;
}
return true;
}
public void SendPacket<T>(T t)
{
try
{
if (_socket == null)
Debug.Log("Null socket");
// Encode the data string into a byte array.
byte[] buffer = t.ToJsonBinary();
_event.SetBuffer(buffer, 0, buffer.Length);
// Send the data through the socket.
//_socket.SendAsync(_event);
bool willRaiseEvent = _socket.SendAsync(_event);
//if (!willRaiseEvent)
//{
// SendPacket<T>(t);
//}
}
catch (SocketException e)
{a
Debug.LogException(e);
Debug.Log("Couldn't Send Packet");
}
}
public void SendPacket(string msg)
{
Packet packet = new Packet(_protocolID, msg);
SendPacket<Packet>(packet);
}
}
Json Serialization
public static byte[] ToJsonBinary(this object obj)
{
return Encoding.ASCII.GetBytes(JsonUtility.ToJson(obj));
}
public static T FromJsonBinary<T>(this byte[] data)
{
return JsonUtility.FromJson<T>(Encoding.ASCII.GetString(data));
}
Packet
[Serializable]
public struct Packet
{
public string _protocolID;
public string _msg;
public Packet(string protocolID, string msg)
{
_protocolID = protocolID;
_msg = msg;
}
}
Edit: I found out it's crashing due to Json Utility
System.ArgumentException: JSON parse error: The document root must not follow by other values.
Json string before being sent (top), Json string reiceived at the server (bottom)
It seems on the server the buffer isn't being cleared so it still has information in it.

Okay so it seems the problem was due to how SocketAsyncEventArgs works. Since I'm calling recursively and passing the same event it never clears it's buffer.
if (!_socket.ReceiveAsync(e))
{
OnConnect(null, e);
}
I found two solutions one was to do pass a new SocketAsyncEventArgs which will have a clear buffer. But I believe a better idea would be to make a pool to handle and reuse a set of predefined SocketAsyncEventArgs instead of constantly creating new ones.
Another solution I found was to simple set a new buffer as a way to clear the last one.
byte[] buffer = t.ToJsonBinary();
_event.SetBuffer(buffer, 0, buffer.Length);

Related

How to receive continuously on UDP port and send message on same port when received

The case for my problem is: There is a program running locally acting like a server sending data on request. I can call for data on port 4096.
I would like to create client side which would send the message requested by the "server" ("GET_DATA") and then listen for whole response (several chunks). Then, after validating wholeness
of the data (CheckCompleteData method) or some time, send request "GET_DATA" again and keep listening for the response.
My code so far:
public class Connector
{
private static UdpClient udpClient;
private static List<Byte[]> receivedData;
readonly Byte[] sendBytes = Encoding.ASCII.GetBytes("GET_DATA");
private static IPEndPoint ep;
public Connector(string address, int port, int bufferSize)
{
if (String.IsNullOrEmpty(address))
{
throw new ArgumentNullException();
}
udpClient = new UdpClient();
udpClient.Client.ReceiveBufferSize = bufferSize;
ep = new IPEndPoint(IPAddress.Parse(address), port);
udpClient.Connect(ep);
}
private void SendDataRequest()
{
udpClient.Send(sendBytes, sendBytes.Length);
}
public List<Byte[]> ReceiveAllData()
{
SendDataRequest();
receivedData = new List<byte[]>();
udpClient.BeginReceive(new AsyncCallback(ReceiveData), null);
return receivedData;
}
private static void ReceiveData(IAsyncResult res)
{
receivedData.Add(udpClient.EndReceive(res, ref ep));
udpClient.BeginReceive(ReceiveData, null);
}
}
So far I managed to receive all chunks of one message, but I cannot call ReceiveAllData repeatedly, because the client is already disposed.
I have no idea how to secure continuous listening with calling some event when data received.
Any suggestions ?

TCP Socket client Async - connection handling

I have a problem with connection handling in TCP Client socket.
This code should connect to localhost at 4444 port and listening for all incoming data from this TCP Server.
I need to write connection handling for this. For example if while attempting to connect server is not responding it should trying to connect again, or if connection is ready and after receiving some data TCP server will close the connection TCP client should try to reconnect again.
Can anyone help me with this problems
Here is what I have in this moment
using UnityEngine;
using System.Collections;
using System;
using System.Net;
using System.Net.Sockets;
public class TCPClientNew : MonoBehaviour {
private Socket _clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
private byte[] _recieveBuffer = new byte[8142];
private void StartClient()
{
try
{
_clientSocket.Connect(new IPEndPoint(IPAddress.Loopback,4444));
}
catch(SocketException ex)
{
Debug.Log(ex.Message);
// Try to reconnect ?? TODO
}
Debug.Log ("connected");
_clientSocket.BeginReceive(_recieveBuffer,0,_recieveBuffer.Length,SocketFlags.None,new AsyncCallback(ReceiveCallback),null);
}
private void ReceiveCallback(IAsyncResult AR)
{
//Check how much bytes are recieved and call EndRecieve to finalize handshake
int recieved = _clientSocket.EndReceive(AR);
if(recieved <= 0)
return;
//Copy the recieved data into new buffer , to avoid null bytes
byte[] recData = new byte[recieved];
Buffer.BlockCopy(_recieveBuffer,0,recData,0,recieved);
//Processing received data
Debug.Log (System.Text.Encoding.ASCII.GetString(recData));
//Start receiving again
_clientSocket.BeginReceive(_recieveBuffer,0,_recieveBuffer.Length,SocketFlags.None,new AsyncCallback(ReceiveCallback),null);
}
private void SendData(byte[] data)
{
SocketAsyncEventArgs socketAsyncData = new SocketAsyncEventArgs();
socketAsyncData.SetBuffer(data,0,data.Length);
_clientSocket.SendAsync(socketAsyncData);
}
void Start()
{
StartClient ();
}
}
What you want is a way to keep retrying the connection if it fails. And if there is an exception during a read, you want to see if we're still connect and if not then re-connect. I added a loop in the Connect() method to retry the connect after waiting for 1 second.
In the receive callback, I put a try/catch and if there is an exception I will go back to the Connect() method to retry the connection.
public class TCPClientNew
{
private Socket _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private byte[] _recieveBuffer = new byte[8142];
private void Connect()
{
bool isConnected = false;
// Keep trying to connect
while (!isConnected)
{
try
{
_clientSocket.Connect(new IPEndPoint(IPAddress.Loopback, 4444));
// If we got here without an exception we should be connected to the server
isConnected = true;
}
catch (SocketException ex)
{
Debug.Log(ex.Message);
// Wait 1 second before trying to connect again
Thread.Sleep(1000);
}
}
// We are now connected, start to receive
_clientSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
}
private void ReceiveCallback(IAsyncResult AR)
{
//Check how much bytes are recieved and call EndRecieve to finalize handshake
try
{
int recieved = _clientSocket.EndReceive(AR);
if (recieved <= 0)
return;
//Copy the recieved data into new buffer , to avoid null bytes
byte[] recData = new byte[recieved];
Buffer.BlockCopy(_recieveBuffer, 0, recData, 0, recieved);
//Start receiving again
_clientSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
}
catch (SocketException ex)
{
Debug.Log(ex.Message);
// If the socket connection was lost, we need to reconnect
if (!_clientSocket.Connected)
{
Connect();
}
else
{
//Just a read error, we are still connected
_clientSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
}
}
}
private void SendData(byte[] data)
{
SocketAsyncEventArgs socketAsyncData = new SocketAsyncEventArgs();
socketAsyncData.SetBuffer(data, 0, data.Length);
_clientSocket.SendAsync(socketAsyncData);
}
}

C# socket read buffer error with multiple clients connecting to servers

I write an Windows C# application which can create up to 16 threads. Each thread creates a socket for a remote device. Each thread send commands to read the device status. (every 300 ms) It is OK when I create one or two threads to read the status. But when I create 10 threads to read device status, I will get wrong data in the socket receive buffer.
Please refer to the following for my socket driver code:
class SocketClient {
private IPAddress ipAddress;
private IPEndPoint remoteEP;
private Socket mSocket;
private SocketAsyncEventArgs e = new SocketAsyncEventArgs();
private System.Timers.Timer timer_connection;
private static byte[] response = new byte[1024];
private Boolean waittingConnectDone;
private Boolean boolConnected;
public SocketClient() {
}
private byte[] acknowledge = null;
public Boolean Connect(String IP, int Port) {
Boolean bRet = true;
ipAddress = IPAddress.Parse(IP);
remoteEP = new IPEndPoint(ipAddress, Port);
mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//mSocket.ReceiveTimeout = GlobalVar.ethernet_timeout;
mSocket.ReceiveTimeout = 500;
try {
waittingConnectDone = false;
e.RemoteEndPoint = remoteEP;
e.UserToken = mSocket;
e.Completed += new EventHandler<SocketAsyncEventArgs>(e_Completed);
mSocket.ConnectAsync(e);
if (timer_connection != null) {
timer_connection.Dispose();
} else {
timer_connection = new System.Timers.Timer();
}
timer_connection.Interval = 2000;
timer_connection.Elapsed += new ElapsedEventHandler(timer_connection_Tick);
timer_connection.Start();
while (true) {
if (waittingConnectDone)
break;
Application.DoEvents();
}
bRet = boolConnected;
//sender.Connect(remoteEP);
} catch {
Debug.WriteLine("### Ethernet ### Connection Error!");
bRet = false;
}
return bRet;
}
private void e_Completed(object sender, SocketAsyncEventArgs e) {
boolConnected = true;
waittingConnectDone = true;
}
private void timer_connection_Tick(object sender, EventArgs e) {
if (!mSocket.Connected) {
timer_connection.Stop();
boolConnected = false;
waittingConnectDone = true;
}
}
public void Disconnect() {
try {
mSocket.Shutdown(SocketShutdown.Both);
mSocket.Close();
} catch {
}
}
Each Thread use following code to read the device status:
private byte[] acknowledge = null;
private static byte[] response = new byte[1024];
public byte[] sendCommand(byte[] Cmp_TxData) {
try {
bytesSent = mSocket.Send(Cmp_TxData);
bytesRec = mSocket.Receive(response);
acknowledge = new byte[bytesRec];
Array.Copy(response, 0, acknowledge, 0, bytesRec);
}
catch
{
acknowledge = null;
}
return acknowledge;
}
And the buffer data error is something like following:
TX --> 00-03-01-F4-00-03-44-14
RX <-- 00-00-00-00-00-00-00-00-00-00-00
Sometime I read correct data, but sometimes the data are all 0!
Is there anything wrong with my socket driver?
Really appreciate your help!!
I have not checked all of the posted code (I suspect there may be more errors, multithreading is hard if you try to do it all yourself), but this line:
private static byte[] response = new byte[1024];
Is definitely a source for the types of errors you report. This line declares a buffer that is shared between all threads.
So if multiple threads do this:
bytesRec = mSocket.Receive(response);
The data in this response buffer can be concurrently modified.
To resolve this specific error, you could ensure that you create a static buffer for each thread using [ThreadStatic] or ThreadLocal (see for example http://reedcopsey.com/2009/11/12/thread-specific-data-becomes-easier-in-net-4-0-via-threadlocalt/).

Send text file directly to network printer

I have currently-working code which sends raw data to a printer by writing a temporary file, then using File.Copy() to send it to the printer. File.Copy() supports both local ports, like LPT1 and shared printers like \\FRONTCOUNTER\LabelPrinter.
However, now I'm trying to get it working with a printer that's directly on the network: 192.168.2.100, and I can't figure out the format to use.
File.Copy(filename, #"LPT1", true); // Works, on the FRONTCOUNTER computer
File.Copy(filename, #"\\FRONTCOUNTER\LabelPrinter", true); // Works from any computer
File.Copy(filename, #"\\192.168.2.100", true); // New printer, Does not work
I know it's possible to "Add a printer" from each computer, but I'm hoping to avoid that - the second line of code above works from any computer on the network automatically, with no configuration required. I also know it's possible to P/Invoke the windows print spooler, and if that's my only option I may take it, but that's much more code overhead than I'd like to have.
Ideally, someone will have either a way to make File.Copy() work or a similar C# statement which will accept a network IP.
You can use sockets and send the data straight to that IP address. Should pretty much be the same as File.Copy. I just tried it out and that worked.
I just sent some text but here is the code that I used
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.NoDelay = true;
IPAddress ip = IPAddress.Parse("192.168.192.6");
IPEndPoint ipep = new IPEndPoint(ip, 9100);
clientSocket.Connect(ipep);
byte[] fileBytes = File.ReadAllBytes("test.txt");
clientSocket.Send(fileBytes);
clientSocket.Close();
try this code:
public class PrintHelper
{
private readonly IPAddress PrinterIPAddress;
private readonly byte[] FileData;
private readonly int PortNumber;
private ManualResetEvent connectDoneEvent { get; set; }
private ManualResetEvent sendDoneEvent { get; set; }
public PrintHelper(byte[] fileData, string printerIPAddress, int portNumber = 9100)
{
FileData = fileData;
PortNumber = portNumber;
if (!IPAddress.TryParse(printerIPAddress, out PrinterIPAddress))
throw new Exception("Wrong IP Address!");
}
public PrintHelper(byte[] fileData, IPAddress printerIPAddress, int portNumber = 9100)
{
FileData = fileData;
PortNumber = portNumber;
PrinterIPAddress = printerIPAddress;
}
/// <inheritDoc />
public bool PrintData()
{
//this line is Optional for checking before send data
if (!NetworkHelper.CheckIPAddressAndPortNumber(PrinterIPAddress, PortNumber))
return false;
IPEndPoint remoteEP = new IPEndPoint(PrinterIPAddress, PortNumber);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.NoDelay = true;
connectDoneEvent = new ManualResetEvent(false);
sendDoneEvent = new ManualResetEvent(false);
try
{
client.BeginConnect(remoteEP, new AsyncCallback(connectCallback), client);
connectDoneEvent.WaitOne();
client.BeginSend(FileData, 0, FileData.Length, 0, new AsyncCallback(sendCallback), client);
sendDoneEvent.WaitOne();
return true;
}
catch
{
return false;
}
finally
{
// Shutdown the client
this.shutDownClient(client);
}
}
private void connectCallback(IAsyncResult ar)
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
// Signal that the connection has been made.
connectDoneEvent.Set();
}
private void sendCallback(IAsyncResult ar)
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
// Signal that all bytes have been sent.
sendDoneEvent.Set();
}
private void shutDownClient(Socket client)
{
client.Shutdown(SocketShutdown.Both);
client.Close();
}
}
Network Helper class:
public static class NetworkHelper
{
public static bool CheckIPAddressAndPortNumber(IPAddress ipAddress, int portNumber)
{
return PingIPAddress(ipAddress) && CheckPortNumber(ipAddress, portNumber);
}
public static bool PingIPAddress(IPAddress iPAddress)
{
var ping = new Ping();
PingReply pingReply = ping.Send(iPAddress);
if (pingReply.Status == IPStatus.Success)
{
//Server is alive
return true;
}
else
return false;
}
public static bool CheckPortNumber(IPAddress iPAddress, int portNumber)
{
var retVal = false;
try
{
using (TcpClient tcpClient = new TcpClient())
{
tcpClient.Connect(iPAddress, portNumber);
retVal = tcpClient.Connected;
tcpClient.Close();
}
return retVal;
}
catch (Exception)
{
return retVal;
}
}
}

Send a message back to a list of clients at any given time with async sockets in C#

Ive got an async server set up, it works perfectly by connecting, receiving and sending back a message to the connecting client.
The server itself is a Game-World-Server (mmorpg style). When a user sends its position to where its located, I need to push this out to all the clients with a PlayerPositionNotice. I know I'm missing some basic stuff here, but when i try to save the StateObject that was created in the accept method, and use that socket to send back information to the player at any given time it fails because the socket is closed. =/ Don't know why this happens and would I've searched a couple of engines on this but came back empty.
This is how i created my server:
First off we have the global stuff:
public StateManager _stateManager = new StateManager();
public bool IsClosing = false;
private const int _port = 1025;
private IPHostEntry _localhost;
private IPEndPoint _endpoint;
private Socket _serverSocket;
private Thread _serverThread;
Second of we have the initialize stuff:
public void Start()
{
_serverThread = new Thread(Initialize);
_serverThread.Start();
}
/// <summary>
/// Main entry point for the server
/// </summary>
private void Initialize()
{
Console.WriteLine("Server Main Socket Thread Initialized.");
_localhost = Dns.GetHostEntry(Dns.GetHostName());
try
{
_endpoint = new IPEndPoint(_localhost.AddressList[0], _port);
_serverSocket = new Socket(_endpoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
_serverSocket.Bind(_endpoint);
_serverSocket.Listen(100);
_serverSocket.BeginAccept(new AsyncCallback(acceptCallback), _serverSocket);
}
catch (ArgumentOutOfRangeException)
{
Console.WriteLine(" >> Port number " + _port + " would seem to be invalid, should be between 1024 and 65000");
}
catch (SocketException)
{
Console.WriteLine(" >> Could not create socket, check to make sure not duplicating port");
}
catch (Exception e)
{
Console.WriteLine(" >> Error occured while binding socket, IE:" + e.InnerException);
}
}
So far so good, i expect.. And now to the rest of the server class.
private void acceptCallback(IAsyncResult result)
{
Console.WriteLine("Connection Accepted");
StateObject state = null;
try
{
state = new StateObject
{
workSocket = ((Socket)result.AsyncState).EndAccept(result)
};
_stateManager.AddConnection(state);
state.workSocket.BeginReceive(state.buffer, 0, state.buffer.Length,
SocketFlags.None, new AsyncCallback(receiveCallback), state);
_serverSocket.BeginAccept(new AsyncCallback(acceptCallback), _serverSocket);
}
catch (SocketException)
{
_stateManager.RemoveConnection(state);
_serverSocket.BeginAccept(new AsyncCallback(acceptCallback), _serverSocket);
}
catch (Exception)
{
_stateManager.RemoveConnection(state);
_serverSocket.BeginAccept(new AsyncCallback(acceptCallback), _serverSocket);
}
}
private void receiveCallback(IAsyncResult result)
{
var state = (StateObject)result.AsyncState;
try
{
// Buffer and count bytes read
int bytesRead = state.workSocket.EndReceive(result);
if (!state.workSocket.Connected)
_stateManager.RemoveConnection(state);
if (bytesRead > 0)
{
// Parse the message to the protocol manager and return a reply
var replyingData = ProtocolManager.Parse(state.buffer);
if (replyingData != null)
Send(replyingData, state);
//Queue the next receive
state.workSocket.BeginReceive(state.buffer, 0, state.buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), state);
}
else
{
_stateManager.RemoveConnection(state);
}
}
catch (SocketException e)
{
_stateManager.RemoveConnection(state);
}
}
public bool Send(byte[] message, StateObject state)
{
Console.WriteLine("Sending " + message.Length + " bytes");
if (state != null && state.workSocket.Connected)
{
lock (state.workSocket)
{
//we use a blocking mode send, no async on the outgoing
//since this is primarily a multithreaded application, shouldn't cause problems to send in blocking mode
state.workSocket.Send(message, message.Length, SocketFlags.None);
}
}
else return false;
return true;
}
The stateManager contains a list of StateObject.. Below you can see how i build them.
STATE MANAGER:
public class StateManager
{
private List<StateObject> _connections = new List<StateObject>();
public void AddConnection(StateObject so)
{
lock (_connections)
{
_connections.Add(so);
}
}
public void RemoveConnection(StateObject so)
{
if (so.workSocket != null)
{
so.workSocket.Close();
lock (_connections)
{
_connections.Remove(so);
}
}
}
}
STATE OBJECT
public class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
}
My problem here is that whenever anybody in this list sends something i want to send back a notice to alot of other clients. How and where can i implement this? Anybody that can kick me in the right direction? =)
This code seem to be correct and I don't know why you get "socket is closed" error, but there is another problem: in Send(byte[] message, StateObject state) method, because you call this when receiving from user and send received data back to that user.(not to all other users to notice them)
As you said, if you need to send new location to all other users:
Call this method instead of your Send(byte[] message, StateObject state), when received new location.
public void NoticeAllusers(byte []buffer,StateObject state)
{
foreach(StateObject obj in _stateManager._connections)
{
if (obj != state)
{
obj.workSocket.BeginSend(buffer,<parameters you>...., new AsyncCallback(OnSend) state.workSocket);
}
}
}
public void OnSend(IAsyncResult ar)
{
try
{
Socket sock = (Socket)ar.AsyncState;
sock.EndSend(ar);
}
catch { }
}
I hope it will help a little :)

Categories