0

大家下午好!

项目目标:构建一个带有客户端、控制台和服务器可执行文件的通知程序。只有选定的用户才能收到通知。

问题:有时代码运行良好,一切正常(20% 的运行)。其余时间,它会弄乱数据发送的顺序。

代码:服务器(控制台 = TCPclient):

private void Connect()
{
    string username = ReadFromConsole();

    if (IsUserAllowed(username)) // Receive username
        SendToConsole(bool.TrueString); // Send confirmation
    else
    {
        SendToConsole(bool.FalseString); // Send denial
        console.Close();
        return;
    }

    string messageID = ReadFromConsole(); // Receive MessageID

    string recipientCount = ReadFromConsole();
    int numOfRecipients = int.Parse(recipientCount); // Receive and parse number of recipients

    List<string> recipients = new List<string>();
    for (int i = 0; i < numOfRecipients; i++)
    {
        string recipient = ReadFromConsole();
        recipients.Add(recipient); // Receive recipient, add to list (required for Message)
    }

    string department = ReadFromConsole(); // Receive department string

    string visibleTime = ReadFromConsole(); // Receive visibility timespan

    string expiration = ReadFromConsole(); // Receive expiration datetime

    StoreRTF(messageID); // Receive and store RTF file

    console.Close(); // Connection is done, close

    Message message = new Message(messageID, department, recipients, visibleTime, expiration);
}

控制台(服务器 = TCPclient):

private void SendMessage()
{
    SendToServer(Environment.UserName);
    if (bool.Parse(ReadFromServer()))
    {
        // User is allowed, continue
        string messageID = DateTime.Now.ToUniversalTime().Ticks.ToString();

        SendToServer(messageID); // MessageID

        string recipientCount = lvRecipients.Items.Count.ToString();

        SendToServer(lvRecipients.Items.Count.ToString()); // Amount of recipients

        foreach (string item in lvRecipients.Items) // Loop to send each recipient
        {
            SendToServer(item);
        }

        string department = TB_Department.Text;

        SendToServer(department); // Send department string

        string visibleTime = TimeSpan.FromSeconds(SLIDER_VisibleTime.Value).Ticks.ToString();

        SendToServer(visibleTime); // Send message visibility time

        string expiration = DateTime.Now.ToUniversalTime().AddMinutes(2).ToString();

        SendToServer(expiration); //TODO add UI control for this

        SendRTFToServer(); // Send RTF file

        MessageBox.Show(
            "Your designated MessageID is: " + messageID + Environment.NewLine +
            "Message upload is succesful.",
            "Complete",
            MessageBoxButton.OK);
    }
    else
    {
        // User is not allowed. Report to user. Disconnect (will be managed by the finally block)
        MessageBox.Show("You are not allowed to upload messages to the server.", "Access denied", MessageBoxButton.OK, MessageBoxImage.Stop);
        return;
    }

}

发送和接收部分(控制台/服务器/客户端之间相同):

private void SendToServer(string toSend)
{
    while (server.GetStream().DataAvailable)
    {
        // Should wait
    }

    StreamWriter writer = new StreamWriter(server.GetStream());
    writer.WriteLine(toSend);
    writer.Flush();
}

private void SendRTFToServer()
{
    while (server.GetStream().DataAvailable)
    {
        // Should wait
    }

    File.Open(RTFLocation, FileMode.Open, FileAccess.Read).CopyTo(server.GetStream());

    server.GetStream().Flush();
    server.GetStream().Close();
}

private string ReadFromServer()
{
    server.GetStream().Flush();
    StreamReader reader = new StreamReader(server.GetStream());
    return reader.ReadLine();
}

我也尝试过不同的循环、实现、切换到 byte[]...

经过大量调试后,我一无所获。我已经检查了哪些信息正在离开控制台,并且所有信息都已签出并且顺序正确。但是,在服务器端,它似乎以完全不同的顺序接收它。

有人知道是什么原因造成的吗?

4

1 回答 1

0

我已经找到了如何正确处理这个问题。相关部分的代码可以在这里找到: C# Sockets send/receive questions and questions

希望这可以帮助将来的人!

于 2013-11-23T19:26:18.263 回答