views:

68

answers:

2

the following is part of a socket class that im working on. what i am stuck with is in serverEndAccept i would like to pass/return a string indicating the accept has been successful. for these am i to use delegates? also by declaring delegates would it not breach the application Model isolation? i.e. i need this to be an independent class which could be used by future separate. im sure there is a sane solution to this but being a newcomer to programming, its beyond me at the moment, so i am asking.

thanks.

    public void serverBeginAceept(int serverPort)
    {
        mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, serverPort);

        mainSocket.Bind(ipEndPoint);
        mainSocket.Listen(MAX_CONNECTIONS);
        mainSocket.BeginAccept(new AsyncCallback(serverEndAccept), mainSocket);
    }

    public void serverEndAccept(IAsyncResult iar)
    {
        Socket oldServer = (Socket)iar.AsyncState;
        mainSocket = oldServer.EndAccept(iar);
    }

i guess i could get these methods to return a string! maybe thats the best bet.

+1  A: 

You can create a state class to keep the state of your async action between the begin and end, like so:

class AcceptState
{
    public Socket Socket{ get; set; }
    public string IdString { get; set; }
    public Action<string> Accepted { get; set; }
}

public void serverBeginAceept(int serverPort, string id, Action<string> accepted)
{
    mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, serverPort);

    var state = new AcceptState() {
        Socket = mainSocket,
        IdString = id,
        Accepted = accepted,
    };

    mainSocket.Bind(ipEndPoint);
    mainSocket.Listen(MAX_CONNECTIONS);
    mainSocket.BeginAccept(new AsyncCallback(serverEndAccept), );
}

public void serverEndAccept(IAsyncResult iar)
{
    var state = (AcceptState)iar.AsyncState;
    mainSocket = state.Socket.EndAccept(iar);
    state.Accepted(state.IdString);
}

And you could call it like this with a lambda:

serverBeginAccept(1234, "My ID", s => MessageBox.Show(s));

This would pop a message box with whatever string you passed in when the connection is accepted.

joshperry
very nice! i just thought of what you said! adding/providing an out perimeter on the method call.
iEisenhower
A: 

While joshperry's method is quite excellent, I think for those unfamiliar with actions, delegates are a good way to go. Of course then you have to define the delegate, set it somewhere, and then call it.

bobber205
Action is just a delegate itself, albeit a generic one, saving you from having to write your own. There is also the Func generic delegate if you need to return a result from your delegate execution.
joshperry