отправить несколько файлов по TCP с C # с помощью TcpClient - PullRequest
0 голосов
/ 02 сентября 2010

Я пытаюсь отправить несколько файлов по TCP, используя C # TcpClient, для одного файла он прекрасно работает, но когда у меня несколько файлов, он отправляет только первый.

Вот мой код:

ОТПРАВКА ФАЙЛОВ

try
{
    TcpClient tcpClient = new TcpClient();
    NetworkStream networkStream;
    FileStream fileStream = null;

    tcpClient.Connect(appUpdateMessage.receiverIpAddress, 12000);
    networkStream = tcpClient.GetStream();

    byte[] byteSend = new byte[tcpClient.ReceiveBufferSize];
    string startupPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).Substring(6);

    DirectoryInfo directoriesInfo = new DirectoryInfo(startupPath);
    DirectoryInfo[] directories = directoriesInfo.GetDirectories();
    FileInfo[] files = directoriesInfo.GetFiles();


    for (int iLoop = 0; iLoop < directories.Length; iLoop++)
    {
        FileInfo[] subdirectoryFiles = directories[iLoop].GetFiles();

        foreach (FileInfo fi in subdirectoryFiles)
        {
            fileStream = new FileStream(fi.FullName, FileMode.Open, FileAccess.Read);

            BinaryReader binFile = new BinaryReader(fileStream);

            FileUpdateMessage fileUpdateMessage = new FileUpdateMessage();
            fileUpdateMessage.fileName = fi.Name;
            fileUpdateMessage.fileSize = fi.Length;
            fileUpdateMessage.targetDirectory = fi.Directory.Name;

            MessageContainer messageContainer = new MessageContainer();
            messageContainer.messageType = MessageType.FileProperties;
            messageContainer.messageContnet = SerializationManager.XmlFormatterObjectToByteArray(fileUpdateMessage);

            byte[] messageByte = SerializationManager.XmlFormatterObjectToByteArray(messageContainer);

            networkStream.Write(messageByte, 0, messageByte.Length);

            int bytesSize = 0;
            byte[] downBuffer = new byte[2048];
            while ((bytesSize = fileStream.Read(downBuffer, 0, downBuffer.Length)) > 0)
            {
                networkStream.Write(downBuffer, 0, bytesSize);
            }
            fileStream.Close();
        }
    }
    tcpClient.Close();
    networkStream.Close();

    return true;
}
catch (Exception ex)
{
    //logger.Info(ex.Message);
    return false;
}
finally
{

}

ПРИЕМ ФАЙЛОВ

try
{
    TcpClient tcpClient = c as TcpClient;
    NetworkStream networkstream = tcpClient.GetStream();
    FileStream fileStream = null;
    byte[] _data = new byte[1024];
    int _bytesRead = 0;

    _bytesRead = networkstream.Read(_data, 0, _data.Length);

    MessageContainer messageContainer = new MessageContainer();
    messageContainer = SerializationManager.XmlFormatterByteArrayToObject(_data, messageContainer) as MessageContainer;

    switch (messageContainer.messageType)
    {
        case MessageType.FileProperties:
            FileUpdateMessage fileUpdateMessage = new FileUpdateMessage();
            fileUpdateMessage = SerializationManager.XmlFormatterByteArrayToObject(messageContainer.messageContnet, fileUpdateMessage) as FileUpdateMessage;
            string startupPath = @"d:updatefolder";//System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).Substring(6);

            DirectoryInfo mainDirectory = new DirectoryInfo(startupPath);
            DirectoryInfo targetDirecotry = new DirectoryInfo(startupPath + "\\" + fileUpdateMessage.targetDirectory);

            if (!targetDirecotry.Exists)
            {
                mainDirectory.CreateSubdirectory(fileUpdateMessage.targetDirectory);
            }

            fileStream = new FileStream(startupPath + "\\" + fileUpdateMessage.targetDirectory + "\\" + fileUpdateMessage.fileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
            long filezie = fileUpdateMessage.fileSize;
            int byteSize = 0;

            byte[] downBuffer = new byte[2048];

            while ((byteSize = networkstream.Read(downBuffer, 0, downBuffer.Length)) > 0)
            {
                fileStream.Write(downBuffer, 0, byteSize);
                if (this.InvokeRequired)
                {
                    this.Invoke((MethodInvoker)delegate
                    {
                        //progressBar1.Value = Convert.ToInt32((byteSize * 100) / fileUpdateMessage.fileSize);

                        progressBar1.Value = Convert.ToInt32((fileStream.Length * 100) / fileUpdateMessage.fileSize);
                        lblFileName.Text = fileUpdateMessage.fileName;
                    });
                }
                else
                {
                    //progressBar1.Value = Convert.ToInt32((byteSize * 100) / fileUpdateMessage.fileSize);
                    lblFileName.Text = fileUpdateMessage.fileName;
                }
            }
            fileStream.Close();
            networkstream.Close();
            break;
    }
}
catch (Exception ex)
{
    //logger.Error(ex.Message);
}

Есть идеи, что я делаю не так?

Ответы [ 3 ]

1 голос
/ 22 мая 2012

В вашем коде отправки у вас есть цикл, в котором вы отправляете несколько файлов.На принимающей стороне я не вижу соответствующей петли.

Вы можете отправить количество файлов, которые должны быть отправлены, и иметь клиентский цикл много раз.Вы также можете послать что-нибудь после конца каждого файла, что будет означать «Здесь идет другой файл» или «Я готов, закройте все сейчас»

1 голос
/ 12 июля 2011

вы должны закрыть поток после отправки файла.

http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.getstream%28v=vs.71%29.aspx

"Примечание Вы должны закрыть NetworkStream, когда вы отправляете и получаете данные. Закрытие TcpClient не освобождаетNetworkStream. "

0 голосов
/ 08 июня 2012

Краткий ответ на этот вопрос: сделайте это как пинг-понг, отправьте первый файл, разрешите клиенту ответить, снова отправьте другой файл, разрешите клиенту ответить и т. Д.

...