Question

I wrote my code using this article at msdn as a primary helper

My code:

    private ManualResetEvent _AllDone = new ManualResetEvent(false);

    internal void Initialize(int port,string IP)
    {
        IPEndPoint _Point = new IPEndPoint(IPAddress.Parse(IP), port);
        Socket _Accpt = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        _Accpt.Bind(_Point);
        _Accpt.Listen(2);

        while (true)
        {
            _AllDone.Reset();
            _Accpt.BeginAccept(null, 0, new AsyncCallback(Accept), _Accpt);
            _AllDone.WaitOne(); <<crash here
        }

    }

This is what happens,I set a breakpoint at BeginAccept(I thought there's the problem),but it steps it normally.However,when I try to step "_AllDone.WaitOne()" - the server crash.

If _allDone can't be used in a win32 form application - how do I make my project?

EDIT

I forgot to mention I wrote _AllDone.Reset() in Accept(),but It doesn't go there,I set a breakpoint there,but it won't go.

    private void Accept(IAsyncResult async)
    {
        _AllDone.Set();
        Socket _Accpt = (Socket)async.AsyncState;
        Socket _Handler = _Accpt.EndAccept(async);

        StateObject _State = new StateObject();
        _State.workSocket = _Handler;

        _Handler.BeginReceive(_State.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), _State);

    }
Was it helpful?

Solution

So if I get it right, you want to re-start Accept as soon as a socket connection is received, and not wait until Accept is done, and that's why you don't use the sync version of Accept.

So you are saying that it does not fire your Accept method when you connect a socket to the specified address and port? Because that's what Accept does: it accepts a new incoming connection, waiting until a client connects. So that may be why you are thinking that it "crashed" and why it never reaches your code in your Accept method.

Hint: maybe also have a look at Socket.AcceptAsync

Edit: To set up an async server listening to incoming connections, you don't need any ManualWaitEvent:

internal void Initialize(int port,string IP) {
    IPEndPoint _Point = new IPEndPoint(IPAddress.Parse(IP), port);
    Socket _Accpt = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    _Accpt.Bind(_Point);
    _Accpt.Listen(2);
    _Accpt.BeginAccept(null, 0, new AsyncCallback(Accept), _Accpt);
}

private void Accept(IAsyncResult async) {
    Socket _Accpt = (Socket)async.AsyncState;
    Socket _Handler;
    try {
        _Handler = _Accpt.EndAccept(async);
    } finally {
        _Accpt.BeginAccept(null, 0, new AsyncCallback(Accept), _Accpt);
    }

    StateObject _State = new StateObject();
    _State.workSocket = _Handler;

    _Handler.BeginReceive(_State.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), _State);
}

Note: You will also need an exit condition, so that the BeginAccept is not called (for instance when you want to shut down the server).

OTHER TIPS

I think that Lucero is trying to say, that the application works normally, you may ask how come.

Well when you are using a server side socket application, what you basically do is to ask the server to liseten to a port and wait for a conection to arrive. when the connection arrives then you do the rest of the code.

What Lucero was saying is, that while no message is arriving to the server the server keeps lisetning and waiting, which might look for you as if it's freezes.

Is it the case in your code?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top