2013-10-25 4 views
0

Добрый день!Передача нескольких команд/решений через гнездо tcp

Цель проекта: Создайте программу уведомления с клиентом, консолью и исполняемым сервером. Уведомление должно получить только выбранные пользователи.

Проблема: Иногда код отлично работает, и все работает (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(); 
} 

Я также пробовал разные циклы, реализации, переключение на байты [] ...

После многих отладочных работ я никуда не ухожу. Я проверил, какая информация покидает консоль, и что все проверяется и находится в правильном порядке. Тем не менее, на сервере он, кажется, получает его в совершенно ином порядке.

У кого-нибудь есть идея, что вызывает это?

+0

Выполняется ли каждая передача по тому же соединению? – Didaxis

+0

Каждое соединение имеет собственный поток, каждое соединение соединения прекращается после отправки всего сообщения. Если клиент повторно подключится, он получит новый поток. –

ответ

0

Я нашел, как правильно справиться с этим. Код для соответствующих частей можно найти здесь: C# Sockets send/receive problems and questions

Надеюсь, это поможет кому-то в будущем!

Смежные вопросы