سؤال

لدي حلقة تفتح المقبس، وتعمل على المقبس، ثم تغلق المقبس وتعيد التشغيل.ومع ذلك، في التكرار الثاني أحصل عليه SocketException, ، يُسمح عادةً باستخدام واحد فقط لكل عنوان مأخذ توصيل (البروتوكول/عنوان الشبكة/المنفذ).
ومع ذلك، ينبغي إغلاق المقبس، netstat -a لا يظهر أنني أستمع على هذا المنفذ أو أي شيء.الكود الذي يطرح الاستثناء هو:

_bindedLocalSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_bindedLocalSocket.Bind(new IPEndPoint(Util.ChannelProfileToListeningAddress(_profile), _profile.ListenPort));
_bindedLocalSocket.Listen(30);
_bindedLocalSocket.BeginAccept(new AsyncCallback(OnRequested), null);

ومع ذلك، أعتقد أن الجاني ليس هذا الرمز، قبل أن أصل إلى هذا الرمز مباشرةً، وقبل أن أحاول إغلاق الاتصال، أحصل على هذا:

An existing connection was forcibly closed by the remote host
   at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
   at Poderosa.PortForwarding.SynchronizedSocket.EndReceive(IAsyncResult ar)
   at Poderosa.PortForwarding.Channel.OnSocketData(IAsyncResult result)

بمجرد إغلاق البرنامج وتشغيله مرة أخرى، يمكن أن يجعل الاتصال الأول جيدًا، ويعمل الاتصال الثاني بنفس الطريقة (SocketException).هل لدى أي شخص أي فكرة كيف يمكنني إصلاح هذا؟

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

المحلول

اعتقدت أن المقبس ()socket.Close يعتني بذلك، لكن لا أعتقد ذلك.في هذه الحالة، تحتاج إلى استخدام:

socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

يمكنك قراءة المزيد عن خيارات المقبس هنا.

نصائح أخرى

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

وهناك طريقة لتعيين waittime لمقبس في. NET يدويا، ولكن قد يكون الخيار الأفضل لإعادة النظر في التصميم الخاص بك، بدلا من ذلك الحفاظ على مقبس المستمع مفتوحة، بدلا من إغلاق عليه، وبدلا من إغلاق الجديدة المقبس الذي يتم إنشاؤه أثناء Socket.Accept ()؛

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