Отправка нескольких данных в TCPSocket - PullRequest
1 голос
/ 02 декабря 2011

Я пытаюсь создать чат с помощью приложения для передачи файлов, используя TCPSocket, и вот мой код ..

SENDER:

public void sendData(string message)
{
    StreamWriter streamWriter = new StreamWriter(netStream); // netStream is 
                                                             // connected   
    streamWriter.WriteLine(message);
    streamWriter.WriteLine(message);
    logs.Add(string.Format("Message Sent! :{0}", message));
    //netStream.Flush();
    streamWriter.Flush();
}

RECEIVER:

private void ReceiveData()
{
    StreamReader streamReader = new StreamReader(ChatNetStream);

    StringBuilder dataAppends = new StringBuilder();
    bool doneTransfer = false;
    string data;
    while (!doneTransfer)
    {
        while ((data = streamReader.ReadLine()) != null)
        {
            dataAppends.Append(data);
        }
        doneTransfer = true;
        //ChatNetStream.Close();
        //streamReader
    }

    //do whatever i want with dataAppends.ToString() here..
   ReceiveData()
}

проблема в том, что я всегда превращаюсь в бесконечный цикл внутри этого оператора

while ((data = streamReader.ReadLine()) != null)
{
    dataAppends.Append(data);
}

, даже если я помещаю streamWriter.Flush () на моего отправителя.

нужно ли мне закрывать / удалятьnetStream / NetworkStream?

В любом случае, могу ли я использовать только 1 сокет или соединение для отправки файла и одновременной отправки чата?или мне нужно использовать новое сокетное соединение каждый раз, когда я отправляю файл ..

Ответы [ 2 ]

1 голос
/ 02 декабря 2011

Вы получаете бесконечный цикл, потому что StreamReader.ReadLine вернет null только когда достигнут конец потока.Для сетевого потока «конец потока» означает «другая сторона закрыла свою половину соединения».Поскольку другая сторона является вашим клиентом и поддерживает соединение открытым, ожидая, пока пользователь введет больше данных, вы получите бесконечный цикл.

Вместо этого вам нужно запуститьоперация, которая завершается, только если есть больше данных для чтения.Есть два способа сделать это: либо использовать блокирующую операцию чтения (в выделенном потоке, чтобы вы не блокировали другую обработку вашего приложения во время ожидания сообщений), либо использовать асинхронную (на основе событий или обратного вызова)подход.

Для синхронного (блокирующего) подхода см. документацию по NetworkStream.Read, которая включает пример кода, показывающего, как проверить, есть ли входящие данные и как вы можете их прочитать.Единственное, что вам абсолютно необходимо знать, это то, что когда Read возвращает ноль, это означает, что все данные были прочитаны, а соединение было закрыто с другой стороны (так что вы также должны закрыть свой конец, а не цикл;клиент отключился).

Для низкоуровневых операций чтения асинхронной сети соответствующей операцией является NetworkStream.BeginRead, которая имеет собственный пример.

Оба подхода ниже- уровень выше, чем у вас в настоящее время, и вам потребуется вручную собрать данные в буфере и решить, когда «достаточно данных» (т. е. полная строка) накопилось для обработки.Затем вам нужно будет осторожно извлечь эти данные из буфера и продолжить.

Для более высокого уровня подхода, который все еще позволяет вам в некоторой степени управлять вещами, изучите , используя клиентские сокеты (и, в частности, две опции синхронизации и асинхронности там).Эта функциональность представлена ​​классами TcpClient (и на стороне сервера соответствующими TcpListener) классами.

Наконец, как сказано в комментарии jValdron, вы либоДля передачи файловых данных требуется отдельное соединение или . Разработайте какой-нибудь специальный протокол, который позволяет чередовать несколько типов данных в одном и том же сетевом потоке.Второе решение, как правило, имеет больше технических преимуществ, но вам также будет сложнее правильно его реализовать.

0 голосов
/ 19 декабря 2011

Ознакомьтесь с примером BasicSend в networkComms.net , который демонстрирует простое приложение для чата с использованием библиотеки с открытым исходным кодом.

...