Добрый день!Передача нескольких команд/решений через гнездо 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();
}
Я также пробовал разные циклы, реализации, переключение на байты [] ...
После многих отладочных работ я никуда не ухожу. Я проверил, какая информация покидает консоль, и что все проверяется и находится в правильном порядке. Тем не менее, на сервере он, кажется, получает его в совершенно ином порядке.
У кого-нибудь есть идея, что вызывает это?
Выполняется ли каждая передача по тому же соединению? – Didaxis
Каждое соединение имеет собственный поток, каждое соединение соединения прекращается после отправки всего сообщения. Если клиент повторно подключится, он получит новый поток. –