简体   繁体   中英

File transfer issue in c#

I am transferring files using c#. I have used this code. The problem is small files like .txt files are transferred correctly but not big files like images, documents, pdf, ppt. Sometimes code works fine but most of the times it transfers less amount of data.

Server Code:

Socket clientSock = sock.Accept();

byte[] clientData = new byte[1024 * 50000];
int receivedBytesLen = clientSock.Receive(clientData);
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);
bWrite.Close();
clientSock.Close();

Client Code:

byte[] fileNameByte = Encoding.ASCII.GetBytes(fileName);
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);
clientSock.Connect(ipEnd);
clientSock.Send(clientData);
clientSock.Close();

Complete code is given in the above link. I have also seen this post but this is not helpful.

Sometimes code works fine but most of the times it transfers less amount of data.

That's the nature of Socket.Receive() , it doesn't always return all data that gets sent to it.

You'll have to do a Receive(clientData, 4, 0) first to receive the bytes that indicate the size , then call Receive(clientData) in a loop until you've received size bytes. But beware that the Receive(buffer[], length, offset) overload just as easily as any other overload can return less than the expected amount of bytes. So you'll also have to call that in a loop:

Something like this:

// First receive the size
int sizeSize = 4; // Size of Int32 in bytes
int sizeOffset = 0;
var sizeBytes = new byte[sizeSize];
while (sizeOffset < sizeSize)
{
    sizeOffset += clientSocket.Receive(sizeBytes, sizeSize - sizeOffset, sizeOffset);
}

var size = BitConverter.ToInt32(sizeBytes, 0);

// Then receive the data
byte[] fileData = new byte[size];
byte[] clientData = new byte[8192];
int totalBytes = 0;

while (totalBytes < size)
{
    // This may return anything between 0 and 8192, even if not all sent data has been received yet. It may be in a buffer somewhere, waiting to be picked up. Check for 0, since that's when the client disconnects.
    int bytesReceived = clientSocket.Receive(clientData);

    // You now have received a chunk of data of bytesReceived length. Append it into the fileData array.
    Buffer.BlockCopy(clientData, 0, fileData, totalBytes, bytesReceived);

    totalBytes += bytesReceived;
}

As CodeCaster's answered that Socket.Receive(), it doesn't always return all data that gets sent to it. This is 100% correct and tested but the next step of sending the file size is not working, I found an easy and correct solution.

Socket.Receive() method takes the byte array in which received data will be copied and returns the number of bytes received. So we can easily loop it till bytes received are 0.

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

BinaryWriter bWrite = null;
int bytes_received;
int fileNamelength = 0;
bool isFirstPacket = true;

do
{
    bytes_received = clientSock.Receive(tempData);
    if(isFirstPacket)
    {
        isFirstPacket = false;
        int fileNameLen = BitConverter.ToInt32(tempData, 0);
        string fileName = Encoding.ASCII.GetString(clientData, 4, fileNameLen);

        bWrite = new BinaryWriter(File.Open(receivedPath + fileName, FileMode.Append))
        bWrite.Write(tempData, 4 + fileNameLength, bytes_received - 4 - fileNamelength);
    }
    else
        bWrite.Write(tempData, 0, bytes_received);
}
while (bytes_received != 0);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM