예제 #1
0
 public void AddBytes(int bytes, ByteType typ)
 {
     if (typ != ByteType.Sent)
     {
         rc.AddBytes((uint)bytes);
         NetworkReceived += (ulong)bytes;
         return;
     }
     sc.AddBytes((uint)bytes);
     NetworkSent += (ulong)bytes;
 }
예제 #2
0
        public void ReadCallback(IAsyncResult ar)
        {
            //int fileNameLen = 1;
            //String content = String.Empty;
            StateObject tempState = (StateObject)ar.AsyncState;
            Socket      handler   = tempState.workSocket;
            int         bytesRead = handler.EndReceive(ar);

            if (bytesRead <= 0)
            {
                return;
            }

            counter.AddBytes((uint)bytesRead);

            if (isFirstPacket)
            {
                try
                {
                    // gets the first byte
                    byte[] firstByte = new byte[1];
                    firstByte = tempState.buffer.Take(1).ToArray();

                    // first byte has a value 0 - 255
                    fileNameLength = Convert.ToInt32(firstByte[0]);

                    // a fileName cannot be more then 255 characters because a byte cannot have have a higher value...
                    if (fileNameLength > 255)
                    {
                        // filename is not valid...
                        // this should not happen, should somehow at least validate the first packet to ensure
                        // it contain the right information...
                        return;
                        //fileNameLength = 255;
                    }

                    // TODO:
                    // check if fileName is valid
                    // if file already exist (conflict)

                    fileName = Encoding.ASCII.GetString(tempState.buffer, 1, fileNameLength);
                    //receivePath += "\\" + fileName;

                    // after the file name comes the size of the file
                    // should be a long
                    // that is 64 bit = 8 byte
                    byte[] fileSizeB = tempState.buffer.Skip(1 + fileNameLength).Take(8).ToArray();
                    fileSize = BitConverter.ToInt64(fileSizeB, 0);

                    // set total to be received
                    totalBytesToBeReceived = fileNameLength + fileSize + 9;

                    // TODO:
                    // get FileInfo object

                    // TODO:
                    // start download counter, datetime, total filesize to download etc
                    // get MD5 hash or other hash of file
                    // make sure all meta data and other stuff is actually sent
                    // calculate hash of when file has been received and written to a file here
                    // close socket and stop thread when entire file has been written

                    // start timer that will execute an event every 1 sec
                    // that shows mb/s kb/s etc
                    timer = new System.Timers.Timer()
                    {
                        Interval = 1000, Enabled = true
                    };
                    timer.Elapsed += timer_Elapsed;
                    timer.Start();
                }
                catch (InvalidCastException castError)
                {
                    // was not able to find file size
                    Console.WriteLine(castError.Message);
                    return;
                }
                catch (Exception error)
                {
                    Console.WriteLine(error.Message);
                    return;
                }
            }

            BinaryWriter writer = null;

            try
            {
                // TODO:
                // double check that file path is correct

                // TODO:
                // only open file while it is not in use
                // wait until file is ready to be written to

                if (isFirstPacket)
                {
                    // old way
                    //writer = new BinaryWriter(File.Open(savePathAndFileName, FileMode.Append));

                    string savePathAndFileName = receivePath + "\\" + fileName;

                    // creates a thread pool using BlockingCollection
                    // this will allow a queue of max 200 threads waiting to write to the file
                    // if more than 200 threads are created, they are blocked and wait until the '
                    // queue is free
                    fileWriter = new ParallelFileWriter(savePathAndFileName, 200);

                    // the first packet contain information that should not be written to the file itself so
                    // if first packet then increase the index to size of fileName + one byte
                    // since we increase the index, we need to reduce the count by the same amount

                    // + 1 byte for size of fileName byte
                    // + 8 bytes for 64 bit long with file size
                    // shift = 9 bytes + fileName
                    int shift = fileNameLength + 9;
                    //writer.Write(tempState.buffer, shift, bytesRead - shift);

                    byte[] data = new byte[bytesRead - shift];
                    Array.Copy(tempState.buffer, shift, data, 0, bytesRead - shift);

                    fileWriter.Write(data);

                    isFirstPacket = false;

                    // set fileName, but do not trigger event
                    FileTransferEvents.filename = fileName;
                }
                else
                {
                    byte[] data = new byte[bytesRead];
                    Array.Copy(tempState.buffer, 0, data, 0, bytesRead);

                    fileWriter.Write(data);

                    //writer.Write(tempState.buffer, 0, bytesRead);
                }

                // TODO:
                // for each byte that has been read, update download counter
                // based on time and bytes received both mb/s and percentage downloaded
                // should be calculated in real time
                // create event

                // add to written files
                totalBytesReceived += bytesRead;

                // TODO:
                // check if all bytes has been read and transfer is complete
                if (totalBytesReceived == totalBytesToBeReceived)
                {
                    // trigger file received event
                    FileTransferEvents.FileReceived = fileName;

                    // reset connection
                    // set everything back to default and wait for new file
                    resetConnection();
                }
            }
            catch (Exception error)
            {
                Console.WriteLine(error.Message);
                Thread.Sleep(30);
            }
            finally
            {
                if (writer != null)
                {
                    writer.Close();
                }



                // triggers event with long of bytes written
                //FileTransferEvents.BytesReceived = written;

                // this method starts a new  AsyncCallback(ReadCallback)
                // and this method is ReadCallback so it works as a recursive method
                handler.BeginReceive(tempState.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), tempState);

                //Thread.CurrentThread.Interrupt();
            }
        }
예제 #3
0
        public void sendFile()
        {
            //BinaryReader bin = null;
            FileInfo file = null;

            // attempt to get read from file
            Console.WriteLine("Attempting to read from file...");
            try
            {
                // get file info
                file = new FileInfo(filePath);

                // only open file again if it has not already been opened
                // if the binaryReader is already set, continue where it left off
                if (bin == null)
                {
                    bin = new BinaryReader(File.OpenRead(filePath));
                }
            }
            catch (Exception error)
            {
                Console.WriteLine("Error reading file: " + error.Message);
                return;
            }

            // attempt to connect
            Console.WriteLine("Attempting to connect...");
            try
            {
                // Create a TCP socket.
                sendingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //sendingSocket.SendBufferSize = 8192;
                sendingSocket.SendBufferSize = 10240;
                //sendingSocket.SendBufferSize = 65536;

                // Don't allow another socket to bind to this port.
                // Should perhaps consider this one
                //listener.ExclusiveAddressUse = true;

                // Connect the socket to the remote endpoint.
                sendingSocket.Connect(endPoint);
            }
            catch (SocketException socketError)
            {
                Console.WriteLine("Error connecting: " + socketError.Message);

                // cannot connect, attempt to reconnect
                // reconnect every x ms, 1000 ms = 1 sec

                // this method will call itself basically (recursive)
                attemptToReconnect();
                return;
            }
            catch (Exception error)
            {
                Console.WriteLine("Error: " + error.Message);
                return;
            }

            Console.WriteLine(String.Format("Connected to {0}:{1}", endPoint.Address.ToString(), endPoint.Port));

            if (isFirstPacket)
            {
                // send prebuffer
                Console.WriteLine("Calculating md5 hash of file...");
                sendingSocket.Send(getPreBuffer());
            }

            Console.WriteLine("Sending file.");

            // trigger event
            FileTransferEvents.TransferStarted = file.Name;

            // set amount of bytes to be receieved
            totalBytesToBeSent = (ulong)file.Length;

            // start bandwith counter
            if (counter == null)
            {
                totalBytesSent = 0;
                counter        = new BandwidthCounter();
            }

            // start timer to trigger kb/s mb/s progress event
            timer_calc_speed = new System.Timers.Timer()
            {
                Interval = 1000, Enabled = true
            };
            timer_calc_speed.Elapsed += timer_calc_speed_Elapsed;
            timer_calc_speed.Start();

            // create buffer
            //byte[] buff = new byte[2048];
            byte[] buff = new byte[10240];

            // loop through file
            while (totalBytesSent < totalBytesToBeSent)
            {
                try
                {
                    // TODO:
                    // if part of the file has been transfered already
                    // then the connection dropped and then a reconnect happened
                    // make sure the transfer continue where it left off and don't
                    // just start from the beginning again.


                    //sending buff's length.
                    totalBytesSent += (ulong)buff.Length;

                    //p.Sock.Send(bin.ReadBytes(buff.Length));
                    sendingSocket.Send(bin.ReadBytes(buff.Length));

                    // add to counter
                    counter.AddBytes((uint)buff.Length);
                }
                catch (SocketException socketError)
                {
                    Console.WriteLine("Error connecting: " + socketError.Message);
                    attemptToReconnect();

                    return;
                }
                catch (Exception error)
                {
                    Console.WriteLine("Error transfering: " + error.Message);

                    // close file
                    if (bin != null)
                    {
                        bin.Close();
                    }

                    resetConnection();
                    return;
                }
                finally
                {
                }
            }

            // close file
            if (bin != null)
            {
                bin.Close();
            }

            resetConnection();

            FileTransferEvents.Percentage = 100;
            Console.WriteLine("File sent");
        }
예제 #4
0
        public void ReadCallback(IAsyncResult ar)
        {
            StateObject tempState = (StateObject)ar.AsyncState;
            Socket      handler   = tempState.workSocket;

            // handle connection problems
            int bytesRead = 0;

            try
            {
                bytesRead = handler.EndReceive(ar);
            }
            catch (SocketException socketError)
            {
                Console.WriteLine("Socket error while transfering: " + socketError.Message);
                Console.WriteLine("Reseting connection...");
                resetConnection();
            }
            catch (Exception error)
            {
                Console.WriteLine("Error while transfering: " + error.Message);
                return;
            }

            if (bytesRead <= 0)
            {
                return;
            }

            // add to counter
            counter.AddBytes((uint)bytesRead);

            if (isFirstPacket)
            {
                try
                {
                    // gets the first byte
                    byte[] firstByte = new byte[1];
                    firstByte = tempState.buffer.Take(1).ToArray();

                    // first byte has a value 0 - 255
                    fileNameLength = Convert.ToInt32(firstByte[0]);

                    // a fileName cannot be more then 255 characters because a byte cannot have have a higher value...
                    if (fileNameLength > 255)
                    {
                        // filename is not valid...
                        // this should not happen, should somehow at least validate the first packet to ensure
                        // it contain the right information...
                        return;
                        //fileNameLength = 255;
                    }

                    // TODO:
                    // check if fileName is valid

                    // Windows 1252 encoding
                    Encoding encoding1252 = Encoding.GetEncoding(1252);
                    fileName = encoding1252.GetString(tempState.buffer, 1, fileNameLength);

                    // after the file name comes the size of the file
                    // should be a long
                    // that is 64 bit = 8 byte
                    byte[] fileSizeB = tempState.buffer.Skip(1 + fileNameLength).Take(8).ToArray();
                    fileSize = BitConverter.ToInt64(fileSizeB, 0);

                    // get md5 hash
                    // md5 hash is 16 bytes = 128 bit
                    md5 = tempState.buffer.Skip(1 + fileNameLength + 8).Take(16).ToArray();

                    // set total to be received
                    totalBytesToBeReceived = fileNameLength + fileSize + 9 + 16;

                    // TODO:
                    // get FileInfo object

                    // TODO:
                    // start download counter, datetime, total filesize to download etc
                    // get MD5 hash or other hash of file
                    // make sure all meta data and other stuff is actually sent
                    // calculate hash of when file has been received and written to a file here
                    // close socket and stop thread when entire file has been written

                    // start timer that will execute an event every 1 sec
                    // that shows mb/s kb/s etc
                    timer = new System.Timers.Timer()
                    {
                        Interval = 1000, Enabled = true
                    };
                    timer.Elapsed += timer_Elapsed;
                    timer.Start();
                }
                catch (InvalidCastException castError)
                {
                    // was not able to find file size
                    Console.WriteLine(castError.Message);
                    return;
                }
                catch (Exception error)
                {
                    Console.WriteLine(error.Message);
                    return;
                }
            }

            BinaryWriter writer = null;

            try
            {
                // TODO:
                // only open file while it is not in use
                // wait until file is ready to be written to

                if (isFirstPacket)
                {
                    // old way
                    //writer = new BinaryWriter(File.Open(savePathAndFileName, FileMode.Append));

                    // TODO:
                    // check that file name and path is correct

                    string savePathAndFileName = receivePath + "\\" + fileName;

                    // check if file already exist
                    // if it does, simply append to the file
                    if (File.Exists(savePathAndFileName))
                    {
                        // TODO:
                        // check if md5 hash of existing file is correct
                        // if so, stop transfer

                        // TODO:
                        // if md5 hash is not the same, check file size of existing file
                        // if its bigger than it's supposed too, remove it
                        // if not, start appending to the file


                        Console.WriteLine("File already exist, appending to file...");
                        fileWriter = new ParallelFileWriter(savePathAndFileName, 200, true);
                    }
                    else
                    {
                        // creates a thread pool using BlockingCollection
                        // this will allow a queue of max 200 threads waiting to write to the file
                        // if more than 200 threads are created, they are blocked and wait until the '
                        // queue is free
                        fileWriter = new ParallelFileWriter(savePathAndFileName, 200);
                    }

                    // the first packet contain information that should not be written to the file itself so
                    // if first packet then increase the index to size of fileName + one byte
                    // since we increase the index, we need to reduce the count by the same amount

                    // + 1 byte for size of fileName byte
                    // + 8 bytes for 64 bit long with file size
                    // + 16 bytes for md5 hash
                    // shift = 9 bytes + fileName
                    int shift = fileNameLength + 9 + 16;
                    //writer.Write(tempState.buffer, shift, bytesRead - shift);

                    byte[] data = new byte[bytesRead - shift];
                    Array.Copy(tempState.buffer, shift, data, 0, bytesRead - shift);

                    fileWriter.Write(data);

                    isFirstPacket = false;

                    // set fileName, but do not trigger event
                    FileTransferEvents.filename = fileName;
                }
                else
                {
                    byte[] data = new byte[bytesRead];
                    Array.Copy(tempState.buffer, 0, data, 0, bytesRead);

                    fileWriter.Write(data);

                    //writer.Write(tempState.buffer, 0, bytesRead);
                }

                // add to written files
                totalBytesReceived += bytesRead;

                // check if all bytes has been read and transfer is complete
                if (totalBytesReceived == totalBytesToBeReceived)
                {
                    // trigger file received event
                    FileTransferEvents.FileReceived = fileName;

                    // get file location
                    string savePathAndFileName = receivePath + "\\" + fileName;

                    // reset connection
                    // set everything back to default and wait for new file
                    resetConnection();

                    // close file writer so we can access file again
                    if (writer != null)
                    {
                        writer.Close();
                    }

                    // complete writing tasks and threads
                    fileWriter.Dispose();

                    Console.WriteLine("Calculating md5 hash of received file...");

                    // get md5 hash
                    ChecksumCalc checksum         = new ChecksumCalc();
                    byte[]       md5AfterTransfer = checksum.GetMD5Checksum(savePathAndFileName);

                    // check if md5 received is identical to md5 calculated after transfer
                    bool isIdentical = checksum.checkIfHashisIdentical(md5, md5AfterTransfer);

                    if (isIdentical)
                    {
                        // the hash received before the file transfer is identical to the
                        // hash calculated with the new file
                        Console.WriteLine("SUCCESS: md5 hash match the md5 of received file");
                    }
                    else
                    {
                        // delete file?
                        Console.WriteLine("ERROR: File is corrupt, md5 hash does NOT match the md5 of the file received");
                    }
                }
            }
            catch (Exception error)
            {
                Console.WriteLine(error.Message);
                Thread.Sleep(30);
            }
            finally
            {
                if (writer != null)
                {
                    writer.Close();
                }

                // triggers event with long of bytes written
                //FileTransferEvents.BytesReceived = written;

                // this method starts a new  AsyncCallback(ReadCallback)
                // and this method is ReadCallback so it works as a recursive method
                try
                {
                    handler.BeginReceive(tempState.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), tempState);
                }
                catch (SocketException socketError)
                {
                    Console.WriteLine("Socket error while transfering: " + socketError.Message);
                    Console.WriteLine("Reseting connection...");
                    resetConnection();
                }
                catch (Exception error)
                {
                    Console.WriteLine("Error while transfering: " + error.Message);
                }
            }
        }