Click here to Skip to main content
15,895,142 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Dears
i have the following method that sends files using sockets
C#
public static void SendFile(string path, string fName,int nbOfFiles ,string strCommand, string strIPadd, int iPortNb,ref Socket clientSock)
{
    try
    {
        clientSock.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.SendBuffer, 0);
        byte[] clientData;
        byte[] fileName = Encoding.UTF8.GetBytes(fName); //file name
        byte[] fileData = File.ReadAllBytes(path); //file
        byte[] fileNameLen = BitConverter.GetBytes(fileName.Length); //lenght of file name
        byte[] bCommand = Encoding.UTF8.GetBytes(strCommand);// Command
        byte[] bComandLength = BitConverter.GetBytes(bCommand.Length); // length of command
        byte[] bNBofFiles = { Convert.ToByte(nbOfFiles), }; //nb of files to be sent to server

        clientData = new byte[12 + bCommand.Length + fileName.Length + fileData.Length];

        bComandLength.CopyTo(clientData, 0);
        bCommand.CopyTo(clientData, 4);
        bNBofFiles.CopyTo(clientData, 4 + bCommand.Length);
        fileNameLen.CopyTo(clientData, 8 + bCommand.Length);
        fileName.CopyTo(clientData, 12 + bCommand.Length);
        fileData.CopyTo(clientData, 12 + fileName.Length + bCommand.Length);

        clientSock.Send(clientData);
        strBuild.AppendEntry("Sending Files to Server Succeeded");

    }
    catch (Exception e)
    {
        strBuild.AppendEntry(e.Message);
    }

}


and the method for receiving is

C#
receivedBytesLen = clientSock.Receive(clientDataFiles);

int commandLength = BitConverter.ToInt32(clientDataFiles, 0); //length of command
strCommandReceived = Encoding.ASCII.GetString(clientDataFiles, 4, commandLength);//command received
iNbofFiles = BitConverter.ToInt32(clientDataFiles, 4 + commandLength);//nb of files

int fileNameLen = BitConverter.ToInt32(clientDataFiles, 8 + commandLength);
fileName = Encoding.ASCII.GetString(clientDataFiles, 12 + commandLength, fileNameLen);

strDirectory = terminal.TerminalPath + "\\" + terminal.TerminalID + "\\" + command.CommandPath;
if (!Directory.Exists(strDirectory))
    Directory.CreateDirectory(strDirectory);

if (iNbofFiles > 1)
{
    filePath = terminal.TerminalPath + "\\" + terminal.TerminalID + "\\" + command.CommandPath + "\\" + fileName;
}
else
{
    filePath = terminal.TerminalPath + "\\" + terminal.TerminalID + "\\" + command.CommandPath + "\\" + command.FileName;
}

if (!System.IO.File.Exists(filePath))
    System.IO.File.Create(filePath).Close();

BinaryWriter bWrite = new BinaryWriter(File.Open(filePath, FileMode.Create)); ;
bWrite.Write(clientDataFiles, 12 + fileNameLen + commandLength, receivedBytesLen - 12 - fileNameLen - commandLength);
bWrite.Close();



The problem "Index and count must refer to a location within the buffer" is taking place when i send more than one large files. If i send 3 small files this problem doesn't occur. Any ideas of how i can clean the buffer before sending the next file
i tried to use
clientSock.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.SendBuffer, 0);
and i used 1 instead of 0 and nothing changed

Regards,
Posted
Updated 7-Aug-12 2:08am
v2
Comments
Richard MacCutchan 7-Aug-12 4:12am    
Your question is not clear; what is the 'problem' you refer to?
Sandra Ha 7-Aug-12 6:13am    
Whenever i try to send more than one file,i cannot because the buffer is full, and an exception is thrown, so what i need to do is clean the buffer before i send a new file
Richard MacCutchan 7-Aug-12 6:23am    
You do not need to clean the buffer, just reset the pointers when it is full and start at the beginning again. Also if you get an exception please post the details in your question so people can help you to diagnose the problem.
Sandra Ha 7-Aug-12 7:37am    
When i send a file the buffer is filled and the index of the buffer is pointed at a specific location. When i send the second file the bytes will be written starting from where the buffer index was located. Since the remaining buffer size is smaller than the second file size i am having this error
"Index and count must refer to a location within the buffer"
And what pointers i have to reset if you can specify
Richard MacCutchan 7-Aug-12 8:05am    
Why not just re-use the buffer completely? When the first file has been sent, start filling the buffer from the beginning. Indeed you can dispose of the first buffer after its data has been sent and start a new one for the next file. Using the method you describe, you will obviously run out of space at some time.

1 solution

You should try and use a more logical approach to the transfer. Get the basic details of the file and send that to your receiving station. Then read the file data in 'blocks' and send each block in turn. The receiver should accept each block and rebuild the file by writing each block in turn. You can then repeat this process for any file, or number of files.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900