使用TcpClient使用C#通过TCP发送多个文件

时间:2010-09-02 08:44:52

标签: c# file tcp client

我正在尝试使用C#TcpClient通过TCP发送多个文件,对于单个文件,它工作得很好,但是当我有多个文件时,它只发送第一个文件。

这是我的代码:

发送文件

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 个答案:

答案 0 :(得分:1)

发送文件后必须关闭流。

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

“注意在发送和接收数据时必须关闭NetworkStream。关闭TcpClient不会释放NetworkStream。”

答案 1 :(得分:1)

在您的发送代码中,您有一个循环,您正在发送多个文件。在接收方,我没有看到相应的循环。

您可以发送即将发送的文件数,并让客户端循环多次。你也可以在每个文件结束后发送一些东西,这表示“这里有另一个文件”或“我已完成,现在关闭所有内容”。

答案 2 :(得分:0)

对此的简短回答是,像乒乓球一样,发送第一个文件,让客户回复,再发送另一个文件,让客户回复等等。