Search code examples
c#.netsocketstcpclientfile-transfer

Socket File Transfer sending incomplete files in C#


I am trying my hands on Socket programming in C# (.NET). I have referred to a couple of examples from codeproject, but my file transfer always sends out incomplete data.

Data of very very small sizes works fine like 1kB. But larger files get transferred incomplete, specifically images.

Here's my client code, that sends a file to the server. The clientData stores the binary of the file.

byte[] fileData = File.ReadAllBytes(filePath + fileName);
            byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
            byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);

            fileNameLen.CopyTo(clientData, 0);
            fileNameByte.CopyTo(clientData, 4);
            fileData.CopyTo(clientData, 4 + fileNameByte.Length);

            curMsg = "Connection to server ...";
            clientSock.Connect(ipEnd);
            int count;
            curMsg = "File sending...";
            count = clientSock.Send(clientData);
            MessageBox.Show(count+" "+clientData.Length);

            curMsg = "Disconnecting...";
            clientSock.Close();

While here is my code for the server, that receives the file.

                sock.Listen(100);

            curMsg = "Running and waiting to receive file.";
            Socket clientSock = sock.Accept();

            byte[] clientData = new byte[1024 * 5000];

            int receivedBytesLen = clientSock.Receive(clientData);
            curMsg = "Receiving data...";

            int fileNameLen = BitConverter.ToInt32(clientData, 0);
            string fileName = Encoding.ASCII.GetString(clientData, 4, fileNameLen);

            BinaryWriter bWrite = new BinaryWriter(File.Open(receivedPath +"/"+ fileName, FileMode.Append)); ;
            bWrite.Write(clientData, 4 + fileNameLen, receivedBytesLen - 4 - fileNameLen);

            curMsg = "Saving file...";

            bWrite.Close();
            clientSock.Close();

What is funny is, that when I set a break-point at 'send' on the client, the file gets transferred fine. I am observing the byte counts at both ends and the transfer bytes match when I use a break-point, while when I don't the received bytes are lower than transferred bytes at client.

What am I doing wrong?


Solution

  • You forgot to implement a protocol! To use TCP, you have to design and implement a protocol that defines what bytes will be sent and how the receiver will identify messages or protocol data elements. You haven't done any of this. Your receive code has no way to know whether it has received the entire file or not because there's no protocol to tell it nor any code to implement such a protocol. So of course it gets it wrong -- it has no way to get it right.

    If receivedBytesLen is 1, your code fails horribly.