views:

670

answers:

2

Hello,

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);

    }
+1  A: 

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).

Lucero
Your first statement is right - this is what I want.However,your second statement is wrong.I didn't connect to it with a TCP Client.I just call that code to setup the server.
John
Well, so nothing has crashed so far. The server waits for an incoming client connection and will only call your Accept method when such a connection is received.
Lucero
I think you misunderstand my problem.How do I make it wait without crashing?
John
You wrote: "There's no exception,it only freeze(crash)"But that's exactly what Accept and its variants are supposed to do - until a client connects! Therefore, this is just normal (waiting) behavior.
Lucero
You misunderstand my question - again.The server is a win32 form application.Can't I create a thread and do that inside the thread? If I could do this,please tell me how.
John
What makes you think I misunderstand the question? Using an async pattern (BeginAccept is fine) will do exactly that: call your method in a dedicated thread taken from the thread pool when the call finishes, which (in the case of Accept) is just as soon as a client connects. So where's the problem?
Lucero
The problem is that the program freeze after "AllDone.WaitOne()".I need to use the GUI while the server is waiting for connections.
John
It is not "freezing", you are telling it to wait until a connection is established. There's nothing wrong with the behavior of the .NET framework (in this case at least).
Lucero
Thanks,was it so hard to understand my problem? :(
John
No, I understood it from the start, but was it so hard to understand my answer? I explained why it did wait...
Lucero
A: 

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?