На моем сервере есть черная дыра (TcpClient, TcpListener)

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

Вот код сервера: я использую один поток для каждого подключенного клиента.

public void ProcessClients()
{
    while (IsListening)
    {
        ClientHandler clientHandler = new ClientHandler(listener.AcceptTcpClient());
        Thread thread = new Thread(new ThreadStart(clientHandler.Process));
        thread.Start();
    }
}

Следующий код является частью класса ClientHandler.

public void Process()
{
    while (client.Connected)
    {
        using (MemoryStream memStream = new MemoryStream())
        {
            int read;
            while ((read = client.GetStream().Read(buffer, 0, buffer.Length)) > 0)
            {
                memStream.Write(buffer, 0, read);
            }

            if (memStream.Length > 0)
            {
                Packet receivedPacket = (Packet)Tools.Deserialize(memStream.ToArray());
                File.WriteAllBytes(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), Guid.NewGuid() + receivedPacket.Filename), receivedPacket.Content);
            }
        }
    }
}

На первой итерации я получаю первый отправленный файл, но после этого я ничего не получаю. Я безуспешно пытался использовать Thread.Sleep(1000) в конце каждой итерации.

С другой стороны у меня есть этот код (для клиентов)

.
.
client.Connect();
foreach (var oneFilename in fileList)
    client.Upload(oneFilename);
client.Disconnect();
.
.

Метод загрузки:

public void Upload(string filename)
{
    FileInfo fileInfo = new FileInfo(filename);
    Packet packet = new Packet()
    {
        Filename = fileInfo.Name,
        Content = File.ReadAllBytes(filename)
    };

    byte[] serializedPacket = Tools.Serialize(packet);

    netStream.Write(serializedPacket, 0, serializedPacket.Length);
    netStream.Flush();
}

netStream (NetworkStream) открывается при подключении и закрывается при отключении.

Где черная дыра? Могу ли я отправить несколько объектов, как я пытаюсь это сделать?

Спасибо за ваше время.


person Tute    schedule 28.03.2010    source источник


Ответы (1)


Я предполагаю, что если клиенты загружают несколько файлов, ваш цикл считывает весь поток как один файл на стороне сервера. Где находится «разделитель между файлами»? Как сервер узнает, где заканчивается одно и начинается другое?

person Brian    schedule 29.03.2010
comment
если бы это было так, как бы вы объяснили успешную передачу первого файла? Первая десериализация работает нормально. Я прав? - person Tute; 29.03.2010
comment
Правилен ли его размер? Или это общий размер всех файлов, отправленных клиентом? Как вы проверяете, что файл получен правильно? - person Brian; 29.03.2010
comment
да, его размер правильный, и md5 тоже такой же, как и первый переданный файл. Файлы представляют собой изображения, поэтому их довольно легко проверить, но я также использую внешний инструмент для проверки контрольной суммы md5. - person Tute; 29.03.2010
comment
Знаете, я нашел еще один сайт (devblog.antongochev.net/2008/07/01/), и он использует разделитель, как вы сказали, даже с сериализованными объектами. Попробую это. - person Tute; 29.03.2010
comment
Да, это была проблема. Спасибо!. - person Tute; 30.03.2010