2013-08-25 40 views
1

我有一个代码发送一个XML文件到UdpSocket并收到答案。我发送并接收到异步答案。我的问题是,当我从UDP套接字接收到答案时,我无法将其保存到正确的文件。我尝试了很多东西,但没有任何效果。为什么我使用Asynchronous UDP client socket随机接收UDP套接字答案?

简短地解释我的代码。我开始在Main()方法中创建3个AsynchronousConnection。从那里调用静态无效AsynchronousConnection(对象objectFilename),我称之为UdpStartClient方法。我发送一个UdpSendXmlFile(fileToSend,udpClient,bytes,CallDuration,out threadId)的文件;我用UdpSendXmlFile(fileToSend,udpClient,bytes,CallDuration,out threadId)发送一个文件。然后,我用方法UdpReceivedXmlFile(“c:\ Received”+文件名,udpClient,remoteEPReceived,CallDuration,out threadId)在while循环中收到答案。

我在UdpReceivedXmlFile方法中收到的答案将保存到文件中。我想这是我的问题。我通过AsynchronousConnection发送3个文件,并从UDP套接字收到3个答案,但答案与我发送的文件不匹配。

例如,我发送这3个文件。

MessagingText4000.xml

MessagingText4001.xml

MessagingText8.xml

我随机接受了答案,例如:

文件MessagingText4000.xml可以从MessagingText8.xml答案

文件MessagingText4001.xml可以从MessagingText4000.xml中得到答案

文件MessagingText8.xml可以从MessagingText4001.xml

你能帮我的答案,所以我接受了正确的答案正确的文件?

public delegate void AsyncMethodCall(object objectFilename, int callDuration, out int threadId, out string receivedXmlDataFromTNX);

// Program 
public static void Main(String[] args) 
{ 
    Thread newThread; 
    newThread = new Thread(AsynchronousConnection); 
    newThread.Name = "4001"; 
    newThread.Start("MessagingText4001.xml"); 

    newThread = new Thread(AsynchronousConnection); 
    newThread.Name = "4000"; 
    newThread.Start("MessagingText4000.xml"); 

    newThread = new Thread(AsynchronousConnection); 
    newThread.Name = "8"; 
    newThread.Start("MessagingText8.xml"); 
} 


// Asynchronous Connection 
static void AsynchronousConnection(object objectFilename) 
{ 
    int threadId; string receivedXmlData; 
    UdpClass udpClass = new UdpClass(); 
    AsyncMethodCall caller = new AsyncMethodCall(udpClass.UdpStartClient); 
    IAsyncResult result = caller.BeginInvoke(objectFilename, 500, out threadId, out receivedXmlData, null, null); 
    result.AsyncWaitHandle.WaitOne(); 
    caller.EndInvoke(out threadId, out receivedXmlData, result); 
    result.AsyncWaitHandle.Close(); 
} 


// UdpClient received 
void UdpReceivedXmlFile(object objectFilename, UdpClient udpClient, IPEndPoint remoteEPReceived, int CallDuration, out int threadId) 
{ 
    Thread.Sleep(CallDuration); 
    threadId = Thread.CurrentThread.ManagedThreadId; 
    try 
    { 
    // Blocks until a message returns on this socket from a remote host. 
    Byte[] receiveBytes = udpClient.Receive(ref remoteEPReceived); 
    File.WriteAllText((string)objectFilename, Encoding.UTF8.GetString(receiveBytes)); 
    } 
    catch (Exception ex) 
    { 
    Console.WriteLine("Contact webmaster with this error in UdpReceivedXmlFile:\n " + ex.ToString()); 
    } 
} 


// UdpClient send 
void UdpSendXmlFile(string fileToSend, UdpClient udpClient, byte[] bytes, int CallDuration, out int threadId) 
{ 
    Thread.Sleep(CallDuration); 
    threadId = Thread.CurrentThread.ManagedThreadId; 
    try 
    { 
    // Encode the data string into a byte array 
    XmlDocument xmlDoc = new XmlDocument(); 
    xmlDoc.Load(fileToSend); 
    // Load XML fil 
    string xmlContent = xmlDoc.OuterXml; 
    byte[] msg = Encoding.UTF8.GetBytes(xmlDoc.OuterXml); 
    // Send the data through the socket. 
    udpClient.Send(msg, msg.Length); 
    } 
    catch (Exception ex) 
    { Console.WriteLine("Contact webmaster with this error in UdpSendXmlFile:\n " + ex.ToString()); 
    } 
} 


// UdpStart Client 
public void UdpStartClient(object objectFilename, int CallDuration, out int threadId, out string receivedXmlData) 
{ 
    string filename = (string)objectFilename; 
    receivedXmlData = null; Thread.Sleep(CallDuration); 
    threadId = Thread.CurrentThread.ManagedThreadId; 
    try 
    { 
    Console.WriteLine("1: UdpStartClient Async - id: " + threadId + " objectFilename: " + (string)objectFilename); 
    fileToSend = fileLocation + filename; 
    // Send a file to the UdpSocket 
    UdpSendXmlFile(fileToSend, udpClient, bytes, CallDuration, out threadId); 

    TimeSpan maxTime = TimeSpan.FromSeconds(10); 
    Stopwatch stopwatch = Stopwatch.StartNew(); 
    bool stopwatchStop = false; 

    while (stopwatch.Elapsed < maxTime && !stopwatchStop) 
    { 
     // listed on UdpSocket and save to file 
     UdpReceivedXmlFileDirectToFile("c:\\Received" + filename, udpClient, remoteEPReceived, CallDuration, out threadId); 
     attributXMLReceived = ReadXmlAttribut("c:\\Received" + filename, CallDuration, out threadId); 

     if ((attributXMLReceived == "Status=Pending") || (attributXMLReceived == "Status=Sent")) 
     { 
     Console.WriteLine("Answer from XMl file:" + attributXMLReceived + " id: " + Thread.CurrentThread.ManagedThreadId + "\n"); 
     } 
     else if (attributXMLReceived == "Status=Delivered") 
     { 
     Console.WriteLine("Answer from XMl file:" + attributXMLReceived + " id: " + Thread.CurrentThread.ManagedThreadId + "\n"); 
     stopwatchStop = true; 
     } 
     if (stopwatch.Elapsed == maxTime) 
     Console.WriteLine("Timeout!"); 
    } 
    } 
    catch (Exception e) 
    { 
    Console.WriteLine(e.ToString()); 
    } 
} 

回答

2

那怎么UDP的作品。

UDP是在连接到IP网络的设备之间提供不可靠,无序的数据传递的协议。它通常被认为是OSI堆栈中的“第4层”协议。 UDP的一种流行用途是传输时间敏感信息,例如IP语音。 UDP在RFC 768

http://www.techabulary.com/u/udp/

你要么需要使用TCP或准备处理的乱序(也可能完全缺失)响应规定。

SCTP是您的传输协议的另一种选择。

+0

+1好答案... stcp也是有序的(http://en.wikipedia.org/wiki/Stream_Control_Transmission_Protocol) – Homer6

+0

我理论上同意你写的东西。但是在一个好的网络中,或者在本地机器上工作时,我不会指望UDP数据报以这种随机顺序出现。难道这与他有3个线程可以以任何顺序运行有关吗? TCP会照顾到这一点,但不仅仅是因为它会对数据包进行排序 - 而是因为您将为每个线程分别进行会话。 – Vadim

+0

我的解决方案是, – MHP