I followed the MSDN example for Asynchronus Sockets. It seems to be working, but I'm having a few issues on how it works. Basically I have two Flash clients that connect to the socket server. I want to be able to send a message from one Flash client to the other. I have been successful in wrtining to the socket and returning the data to the client that sent the message. How do I get the other client to recieve data that is sent to the socket. Is there a way to broadcast to all clients connected to the socket
I'm running VS Studio 2003 Enterprise Edition.
Thanks...

Socket Question
ShawnW277871
Socket handler = listener.EndAccept(ar);
Console.WriteLine("Connected to : "+ handler.RemoteEndPoint);openSockets.Add(handler.RemoteEndPoint);
I then access the ArrayList inside of a loop when I try to send data to the different clients.
I get an error message asking for an EndPoint. I assume its becuase the ArrayList is returning a string. Any idea what I am doing wrong
byte[] byteData = Encoding.ASCII.GetBytes(data);
for(int x =0; x < openSockets.Count; x++)
{
handler.BeginSendTo(byteData, 0, byteData.Length, 0, openSockets[x], new AsyncCallback(SendCallback),handler);
}
lueethefly
It's not a stupid question. Sockets are tricky at first.
Where's the variable "hander" coming from I think what you need to do is store the Socket, not the EndPoint in your collection. Then, iterate through, pulling out each Socket, and use each the unique Socket to send data.
Oh, and once you have your Socket, I think that .BeginSend would be the right method. Not 100% sure, as I've never used .BeginSendTo, but have used .BeginSend.
Mike
Kamran Sorathia
Looks like you figured it out when I was writing that last message. Glad you got it to work.
Mike
Maikel
You can capture the socket when you call Socket.EndAccept(). .EndAccept() returns a socket. Take that socket and store it somewhere - a variable, ArrayList or whatever - then you can use that socket in another method to send data.
Mike
MoinKhan
I tried your suggestion again and captured the Sockets in the ArrayList, I then moved the loop out of the Send function and placed it in side of the ReadCallback function where it calls send. Works great.
Codemachine
If you have a reference to the socket, you can just send data. When I've had multiple clients connect to a server, I've stored the client sockets in a hashtable, then iterate through to send all clients a message.
Mike
Vivian
"handler" is actuall a Socket, but a reference to the state object. I'm gonna post the code. I really don't know where to go next.
using System;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace AsynchSocket
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[ BufferSize];
public StringBuilder sb = new StringBuilder();
}
public class AsynchSocket
{
/// <summary>
/// The main entry point for the application.
/// </summary>
public static ArrayList openSockets = new ArrayList();
public static ManualResetEvent allDone = new ManualResetEvent(false);
public AsynchSocket()
{
}
public static void StartListening()
{
//Databuffer for incoming messages
byte[] bytes = new Byte[ 1024];
//Establish the local endpoint for the socket
//The DNS name of the computer
//Running the listrener is "host.contoso.com"
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");//ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 9999);
//Created a TCP/IP socket
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Bind the Socket to the local endpoint and listen for incoming connections
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
Console.WriteLine("Waiting for a connection...");
while(true)
{
//Set the event to nonsignaled state
allDone.Reset();
//Start an asynchrononus socket to listen for connections.
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
//wait until connection is made before continuing
allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static void AcceptCallback(IAsyncResult ar)
{
//signal the main thread to continue.
allDone.Set();
//Get the Socket that handles the client request.
Socket listener = (Socket) ar.AsyncState;
Socket handler = listener.EndAccept(ar);
Console.WriteLine("Connected to : "+ handler.RemoteEndPoint);
openSockets.Add(handler.RemoteEndPoint);
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
public static void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
//Retrieve the state object and the handler socket
//from the asynchronus state object
StateObject state = (StateObject) ar.AsyncState;
Socket handler = state.workSocket;
//Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
if(bytesRead > 0)
{
//There might be more data so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));
//Check for end of file tag. If it is not there, read more data.
content = state.sb.ToString();
if(content.IndexOf("<EOF>") > -1)
{
//All the data has been read from the
//client. Display it on the console.
//Console.WriteLine("Read{0} bytes from socket. \n Data : {1}",
//content.Length, content);
//Send the data back to flash
Send(handler, content.ToString());
}
else
{
//Not all data received. Get More.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback),state);
}
}
}
//send data back to the client
private static void Send(Socket handler, String data)
{
byte[] byteData = Encoding.ASCII.GetBytes(data);
string[] splitSocket;
for(int x =0; x < openSockets.Count; x++)
{
string s = openSockets[x].ToString();
char[] sep = new char[]{':'};
splitSocket = s.Split(sep);
int socketNum = Int32.Parse(splitSocket[1]);
IPAddress SocketIpAddress = IPAddress.Parse("127.0.0.1");//ipHostInfo.AddressList[0];
IPEndPoint SocketEndPoint = new IPEndPoint(SocketIpAddress, socketNum);
Console.WriteLine(SocketEndPoint);
handler.BeginSendTo(byteData, 0, byteData.Length, 0, SocketEndPoint, new AsyncCallback(SendCallback),handler);
}
}
private static void SendCallback(IAsyncResult ar)
{
try
{
//Retrieve the socket from the state object.
Socket handler = (Socket) ar.AsyncState;
int bytesSent = handler.EndSend(ar);
//handler.Shutdown(SocketShutdown.Both);
//handler.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
StartListening();
return;
}
}
}
ManishaPatil
Try casting back to an EndPoint. ArrayLists store objects. Unless you're using 2.0 and generics.
Mike
Jon Gonzales
I'm not sure about storing the EndPoint instead of the Socket still. Not that I'm exactly sure the best way to go about it, I needed to do the same thing once and mucked around until I got something to work.
In my app, I'm stroring Sockets in a Hashtable, because I need to send data to a particular Socket given a mnemonic.
/// <summary> /// Hashtable to store all client sockets. /// </summary> private Hashtable _clientSockets;I have this method I call to send a message to all clients:
private void sendMessageToAllClients(string message){
try{
foreach(DictionaryEntry de in _clientSockets){
this.sendData((Socket) de.Value, message);}
}
catch(Exception ex){
Logger.Log(ex.ToString());
eventLog.WriteEntry(ex.ToString());
}
}
My sendData() method is overloaded so I can send a string or a byte array:
private void sendData(Socket socket, byte[] data){
try{
socket.BeginSend(data,
0,
data.Length,
SocketFlags.None,
new AsyncCallback(SendCallback),socket);
}
catch(Exception ex){
Logger.Log(ex.ToString());
eventLog.WriteEntry(ex.ToString());
}
}
private void sendData(Socket socket, string data){
sendData(socket, Encoding.ASCII.GetBytes(data));
}
Not sure if that will help you or not, but it works for me. Like I said, I think you want to store the Socket in the ArrayList.
Mike
p.s. Sorry about the formatting. I'm new to this forum and I guess I need to learn how to format properly <g>
Emtiaz
byte[] byteData = Encoding.ASCII.GetBytes(data);
string[] splitSocket;
for(int x =0; x < openSockets.Count; x++)
{
string s = openSockets[x].ToString();
char[] sep = new char[]{':'};
splitSocket = s.Split(sep);
int socketNum = Int32.Parse(splitSocket[1]);
IPAddress SocketIpAddress = IPAddress.Parse("127.0.0.1");//ipHostInfo.AddressList[0];
Console.WriteLine(socketNum + " : socket "+ x );
IPEndPoint SocketEndPoint = new IPEndPoint(SocketIpAddress, socketNum);
handler.BeginSendTo(byteData, 0, byteData.Length, 0, SocketEndPoint, new AsyncCallback(SendCallback),handler);
zkac054