سؤال

كتبت التعليمات البرمجية باستخدام هذه المادة في msdn الأول المساعد

قانون بلدي:

    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
        }

    }

هذا هو ما يحدث ، أنا تعيين نقطة توقف في BeginAccept(اعتقد هناك مشكلة) ، ولكن الخطوات بشكل طبيعي.ومع ذلك ، عندما أحاول أن الخطوة "_AllDone.WaitOne()" - إن تعطل الخادم.

إذا _allDone لا يمكن أن تستخدم في win32 شكل التطبيق - كيف يمكنني أن أجعل المشروع ؟

تحرير

نسيت أن أذكر أنني كتبت _AllDone.إعادة تعيين() في قبول(),ولكن لا تذهب إلى هناك,أنا وضعت نقطة توقف هناك ، لكنه لن يذهب.

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

    }
هل كانت مفيدة؟

المحلول

حتى إذا كنت تحصل عليه الحق ، كنت ترغب في إعادة تشغيل Accept بمجرد اتصال مأخذ توصيل تلقي وعدم الانتظار حتى Accept به ، وهذا هو السبب كنت لا تستخدم مزامنة إصدار Accept.

حتى أنت تقول أنه لا النار الخاص بك تقبل الأسلوب عند توصيل مقبس إلى العنوان المحدد و الميناء ؟ لأن هذا ما نقبل لا:فإنه يقبل جديد الاتصال الوارد الانتظار حتى يتصل عميل.بحيث قد يكون السبب كنت أفكر أنه "تحطمت" و لماذا لم تصل إلى التعليمات البرمجية الخاصة بك في قبول الأسلوب.

تلميح:ربما يكون أيضا نظرة على Socket.AcceptAsync

تحرير: إنشاء المتزامن server الاستماع على الاتصالات الواردة, أنت لا تحتاج إلى أي 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);
}

ملاحظة: سوف تحتاج أيضا شرط الخروج ، بحيث BeginAccept لا يسمى (فعلى سبيل المثال عندما تريد إيقاف تشغيل الملقم).

نصائح أخرى

أعتقد أن لوسيرو يحاول أن يقول أن التطبيق يعمل بشكل طبيعي ، قد تسأل كيف.

وكذلك عند استخدام ملقم الجانب مأخذ التطبيق ، ماذا كنت تفعل في الأساس هو أن تطلب من الخادم إلى liseten إلى ميناء الانتظار كونيكشن للوصول.عند الاتصال يصل ثم تفعل بقية التعليمات البرمجية.

ما لوسيرو كان قوله هو أنه في حين أن أي رسالة وصوله إلى الخادم الخادم يحتفظ lisetning و الانتظار ، والتي قد تبدو لك كما لو كان يتجمد.

هو الحال في القانون ؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top