Question

Good afternoon all!

The goal of the project: Build a notification program with client, console, and server executable. Only selected users should get the notification.

The problem: Sometimes the code works great, and everything works (20% of runs). The rest of the time, it will mess up the order the data is being sent in.

The code: Server (console = 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);
}

Console (server = 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;
    }

}

Send and receive parts (same between console/server/client):

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

I have also tried different loops, implementations, switching to byte[]...

After lots of debugging I am getting nowhere. I have checked which information is leaving the console, and that all checks out and is in the right order. However, at the server end it seems to be receiving it in an entirely different order.

Anyone have an idea what is causing this?

Was it helpful?

Solution

I've found how to properly handle this. Code for the relevant parts can be found here: C# Sockets send/receive problems and questions

Hope this may help someone in the future!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top