Home > front end >  Getting invalid Zip files after sending to a client
Getting invalid Zip files after sending to a client

Time:10-12

I'm trying to send a zip file from a server to client using TCP ports. I'm creating a zip file in a server folder, reading it into a byte array, sending it to a connected client, writing the bytes into a file and storing it in a client folder. Currently the process is just on the same computer.

However, whenever the zip file is saved into the client folder, it's either an invalid zip or a zip with corrupted files. When this happens they'll have the exact same size as the zip file in the server folder, so I don't think I'm losing any bytes in the network transfer. The server zip file also works as expected, you are able to open and view contents in the folder.

The hashes between the client zip and the server zip are different. I've tested with regular .txt, .cs and .csv files, and those are sent and can be opened in the client folder. They have the same has as their server counterpart.

The zip file I'm sending just has a .csv, a .txt, and a .cs file in it.

This is my code

Server:

using System.Net.Sockets;
using System.Net;
using System.Security.Cryptography;
using System.IO.Compression;

String filename = "C:\\BabyServerZip\\ServerFiles.zip";

File.Delete("C:\\BabyServerZip\\ServerFiles.zip");
ZipFile.CreateFromDirectory("C:\\BabyServerSend", "C:\\BabyServerZip\\ServerFiles.zip");

IPHostEntry ipHostInfo = Dns.GetHostEntry("localhost");
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint endpoint = new(ipAddress, 58008);
Socket listener = new(endpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(endpoint);
listener.Listen();

var handler = await listener.AcceptAsync();
var buffer =  new byte[1024];

buffer = File.ReadAllBytes(filename);
handler.Send(buffer);

Client:

using System.Text;
using System.Net;
using System.Net.Sockets;
String outputPath = "C:\\BabyClientReceive\\sent.zip";

IPHostEntry = ipHostInfo = Dns.GetHostEntry("localhost");
IPAddress serverIP = ipHostInfo.AddressList[0];
IPEndPoint clientEnd = new(serverIP, 58008);
Socket clientSocket = new(clientEnd.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
clientSocket.ConnectAsync(clientEnd);

while (true)
{
   if (clientSocket.Available > 0)
   {
      using (StreamWriter fw = new StreamWriter(outputPath))
      {
         char[] response;
         do
         {
            var buffer = new byte[1024];
            int received = clientSocket.Receive(buffer, SocketFlags.None);
            response = Encoding.ASCII.GetChars(buffer, 0, received);
            fw.Write(response, 0, received);
         while (response.Length == 1024);
         fw.Flush();
         fw.Close();
      }
   }
}

Is there something that I'm missing in order to correctly send zip files over a network? Why are the uncompressed files working correctly and the zip files breaking?

CodePudding user response:

Fixed the issue thanks to the tip from @MySkullCaveIsADarkPlace.

StreamWriter is a text writer, and zip files are binary. Switching the StreamWriter for BinaryWriter fixed the problem.

CodePudding user response:

Your client code is all wrong. You are using a StreamWriter as if the Zip is text, but it's not, it's binary. Replacing it with a BinaryWriter is silly also, because that is primarily for writing custom binary formats bit by bit.

There are numerous other issues with the way you are handling this, as you need to expect that the response will not come as a single blob.

Instead you should not use raw sockets, but use TcpClient. You just need to copy the stream straight into a FileStream.

There are also missing await and you should use IPAddress.Any instead of localhost.

String outputPath = "C:\\BabyClientReceive\\sent.zip";
using TcpClient client = new();
await clientSocket.ConnectAsync(IPAddress.Any, 58008);

using (var ns = client.GetStream())
using (var fs = new FileStream(outputPath, FileMode.Create, FileAccess.Write))
{
    await ns.CopyToAsync(fs);
}
  • Related