को अवरुद्ध नहीं करता है हाल ही में मैंने .NET सिंक्रोनस प्राप्त विधि का अजीब व्यवहार किया है। मुझे एक ऐसे एप्लिकेशन को लिखने की ज़रूरत है जिसमें नोड्स हों जो डेटा भेजकर/प्राप्त करके एक-दूसरे के साथ संवाद कर सकें। प्रत्येक सर्वर में एक रसीद लूप होता है जो एक क्रमबद्ध वर्ग प्राप्त करने के बाद सिंक्रोनस होता है, जो इसे deserializes और संसाधित करता है। उसके बाद यह इस क्रमबद्ध कक्षा को कुछ चुने हुए नोड्स (AsynchSendTo का उपयोग करके) के रूप में असीमित रूप से भेजता है।.NET C# सिंक्रोनस रिसीव
MSDN स्पष्ट रूप से कहा गया है कि:
"क्या आप एक कनेक्शन उन्मुख सॉकेट का उपयोग कर रहे हैं, तो के रूप में ज्यादा डेटा पढ़ा जाएगा विधि प्राप्त के रूप में उपलब्ध है, बफर के आकार तक के हैं। रिमोट होस्ट शटडाउन विधि के साथ सॉकेट कनेक्शन को बंद कर देता है, और सभी उपलब्ध डेटा प्राप्त हुए हैं, प्राप्त विधि तत्काल पूर्ण हो जाएगी और शून्य बाइट्स लौटाएगी। "
मेरे मामले में यह सच नहीं है। कुछ यादृच्छिक मामले हैं जब रिसीव ब्लॉक स्थापित नहीं करता है और कनेक्शन स्थापित करने के तुरंत बाद 0 बाइट्स (गैर-निर्धारक अभिवादन) देता है। मुझे 100% यकीन है कि प्रेषक 1000 बाइट्स पर भेज रहा था। एक और मजेदार तथ्य: जब सब कुछ प्राप्त करने से पहले नींद (500) डालने पर बस ठीक काम करता है।
_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
_listener.Bind(_serverEndpoint);
_listener.Listen(Int32.MaxValue);
while (true)
{
Console.WriteLine("Waiting for connection...");
Socket handler = _listener.Accept();
int totalBytes = 0;
int bytesRec;
var bytes = new byte[DATAGRAM_BUFFER];
do
{
//Thread.Sleep(500);
bytesRec = handler.Receive(bytes, totalBytes, handler.Available, SocketFlags.None);
totalBytes += bytesRec;
} while (bytesRec > 0);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
catch (SocketException e)
{
Console.WriteLine(e);
}
इसके अलावा भेजने हिस्सा:
public void AsynchSendTo(Datagram datagram, IPEndPoint recipient)
{
byte[] byteDatagram = SerializeDatagram(datagram);
try
{
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.BeginConnect(recipient, ConnectCallback, new StateObject(byteDatagram, byteDatagram.Length, socket));
}
catch (SocketException e)
{
Console.WriteLine(e);
}
}
public void ConnectCallback(IAsyncResult result)
{
try
{
var stateObject = (StateObject)result.AsyncState;
var socket = stateObject.Socket;
socket.EndConnect(result);
socket.BeginSend(stateObject.Data, 0, stateObject.Data.Length, 0, new AsyncCallback(SendCallback), socket);
}
catch (Exception ex)
{
Console.WriteLine("catched!" + ex.ToString());
}
}
public void SendCallback(IAsyncResult result)
{
try
{
var client = (Socket)result.AsyncState;
client.EndSend(result);
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
class StateObject
{
public Byte[] Data { get; set; }
public int Size;
public Socket Socket;
}
मेरा प्रश्न: मैं तुल्यकालिक उपयोग कर रहा हूँ एक गलत तरीके से प्राप्त इसके अंतर्गत प्राप्त कोड है? डेटा प्राप्त करने के बावजूद यह घटना को अवरुद्ध क्यों नहीं करता है?
चूंकि आपका प्रश्न विशेष रूप से उस समस्या के बारे में नहीं है जिसे आप पढ़ने से पहले नींद के साथ हल कर रहे हैं। आधे सेकेंड के बाद से प्रत्येक लूप वास्तव में विलंबता के साथ एक टोल ले सकता है यदि एक बार में बहुत कुछ पढ़ा जा रहा है, तो क्या आपने 100msecs जैसे छोटे नींद के समय के साथ पढ़ने के बाद सोने की कोशिश की है? इसने सीरियल बंदरगाहों से पढ़ने के लिए मेरे लिए काम किया है, लेकिन यह भी तब हुआ जब एक डेटा प्राप्त हुआ घटना भी हुई। – jlafay
यह सॉकेट काम करने का तरीका नहीं है। सभी प्रयास/पकड़ ब्लॉक को हटाकर इसका निदान करना प्रारंभ करें। –