开发者

send multiple file over TCP with C# using TcpClient

开发者 https://www.devze.com 2023-01-13 22:50 出处:网络
I\'m trying to send multiple files over TCP using C# TcpClient, for a single file it works great, but when I have multiple files, it sends only the first one.

I'm trying to send multiple files over TCP using C# TcpClient, for a single file it works great, but when I have multiple files, it sends only the first one.

Here is my code:

SENDING FILES

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
{

}

RECEIVING FILES

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, messa开发者_如何学编程geContainer) 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);
}

Any idea what I am doing wrong?


you must close the stream after sending a file.

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

"Note You must close the NetworkStream when you are through sending and receiving data. Closing TcpClient does not release the NetworkStream."


In your sending code, you've got a loop where you're sending multiple files. On the receiving side, I don't see a corresponding loop.

You could send the number of files that are about to be sent, and have the client loop that many times. You could also send something after the end of each file, which would indicate "Here comes another file" or "I'm done, close everything now".


Short answer for this is, do it like ping-pong, send first file, let client reply, send again another file, let client reply and so-on.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号