Beispiel #1
0
        /// <summary>
        /// Begins to send a file through the RendezvousData's Transfer socket
        /// </summary>
        /// <remarks>This method cancels the direct connection itself rather than throw an exception</remarks>
        private void BeginSendFile(RendezvousData rd)
        {
            // Open the file for reading
            try
            {
                rd.DirectConnection.DataChunk      = new byte[8192];
                rd.DirectConnection.DataStream     = (new StreamReader(rd.DirectConnection.LocalFileName, false)).BaseStream;
                rd.DirectConnection.StreamPosition = 0;
            }
            catch (Exception ex)
            {
                rd.DirectConnection.CancelTransfer("Can't open file for reading");
                return;
            }

            // Send a PROMPT message and receive an ACK message
            try
            {
                SendFileTransmitterHandshake(rd);
            }
            catch (Exception ex)
            {
                rd.DirectConnection.CancelTransfer(ex.Message);
                return;
            }

            // Signal the parent session that we've started transfering a file
            rd.ParentSession.OnFileTransferProgress(
                RendezvousManager.GetKeyFromCookie(rd.Cookie),
                0, rd.DirectConnection.Header.Size);

            // Send the first chunk
            SendFileTransmitterSendChunk(rd);
        }
Beispiel #2
0
        /// <summary>
        /// Called when a chunk of data has been sent to the remote client
        /// </summary>
        /// <param name="res">An <see cref="IAsyncResult"/> object</param>
        private void SendFileTransmitterSendEnd(IAsyncResult res)
        {
            RendezvousData rd        = (RendezvousData)res.AsyncState;
            int            bytessent = 0;

            try
            {
                bytessent = rd.DirectConnection.Transfer.EndSend(res);
            }
            catch (Exception ex)
            {
                rd.DirectConnection.CancelTransfer(ex.Message);
                return;
            }

            rd.DirectConnection.StreamPosition += (uint)bytessent;

            // Signal parent session of the progress
            rd.ParentSession.OnFileTransferProgress(
                RendezvousManager.GetKeyFromCookie(rd.Cookie),
                rd.DirectConnection.StreamPosition,
                rd.DirectConnection.Header.Size);

            // If all the file has been sent, wait for the acknowledgement message
            // and close up shop. Otherwise, send another chunk
            if (rd.DirectConnection.StreamPosition == rd.DirectConnection.Header.Size)
            {
                byte[] receivedone = new byte[256];
                try
                {
                    rd.DirectConnection.Transfer.Receive(receivedone);
                }
                catch (Exception ex)
                {
                    rd.DirectConnection.CancelTransfer(ex.Message);
                    return;
                }

                // Check checksums?

                rd.DirectConnection.CompleteTransfer();
            }
            else
            {
                SendFileTransmitterSendChunk(rd);
            }
        }
Beispiel #3
0
        /// <summary>
        /// The callback function for socket reads during a file transfer
        /// </summary>
        /// <param name="res">An <see cref="IAsyncResult"/> object</param>
        private void SendFileTransferReceive(IAsyncResult res)
        {
            int               bytesread = 0;
            RendezvousData    rd        = (RendezvousData)res.AsyncState;
            DirectConnectInfo fti       = rd.DirectConnection;

            // End the async receive operation
            try
            {
                bytesread = fti.Transfer.EndReceive(res);
                if (bytesread == 0)
                {
                    throw new Exception("Remote client cancelled transfer");
                }
            }
            catch (Exception ex)
            {
                rd.DirectConnection.CancelTransfer(ex.Message);
                return;
            }

            // Write the received data out to the file
            try
            {
                fti.DataStream.Write(fti.DataChunk, 0, bytesread);
                fti.StreamPosition += (uint)bytesread;
            }
            catch (Exception ex)
            {
                rd.DirectConnection.CancelTransfer(ex.Message);
                return;
            }

            // Checksum the received chunk
            fti.Header.ReceivedChecksum = ChecksumChunk(fti.DataChunk, (uint)bytesread, fti.Header.ReceivedChecksum);

            // Signal progress to the parent session
            rd.ParentSession.OnFileTransferProgress(
                RendezvousManager.GetKeyFromCookie(rd.Cookie),
                rd.DirectConnection.StreamPosition,
                rd.DirectConnection.Header.Size);

            // Check to see if the transfer has finished
            if (fti.StreamPosition >= fti.Header.Size)
            {
                fti.DataChunk = null;
                fti.DataStream.Close();

                // Send out the acknowledgement, compare the checksums, and finish up
                SendFileReceiverDone(rd);

                if (fti.Header.ReceivedChecksum != fti.Header.Checksum)
                {
                    rd.DirectConnection.CancelTransfer("Received data does not match expected checksum");
                    return;
                }

                rd.DirectConnection.CompleteTransfer();
            }
            else
            {
                // Keep receiving asynchronously
                fti.Transfer.BeginReceive(fti.DataChunk, 0, fti.DataChunk.Length,
                                          SocketFlags.None, new AsyncCallback(SendFileTransferReceive), rd);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Receives the PROMPT message and responds with an ACK message, then prepares the transfer socket to receive data
        /// </summary>
        /// <param name="rd">The <see cref="RendezvousData"/> object receiving a file</param>
        private void BeginReceiveFile(RendezvousData rd)
        {
            byte[] filetransferheader = null;
            int    index = 0;

            // Read in 256 bytes, PROMPT type and blank cookie

            filetransferheader = new byte[256];
            try
            {
                while (index < filetransferheader.Length)
                {
                    index += rd.DirectConnection.Transfer.Receive(
                        filetransferheader,
                        index,
                        filetransferheader.Length - index,
                        SocketFlags.None);
                }
            }
            catch (Exception ex)
            {
                string message = "Error negotiating file transfer:" + Environ.NewLine + ex.Message;
                throw new Exception(message);
            }

            index = 8;
            DirectConnectInfo dci = rd.DirectConnection;

            //Marshal.ByteArrayToFTI(filetransferheader, ref index, ref dci);
            rd.DirectConnection = dci; // Just to be sure

            // Respond with the same header, but with the ACK type and the ICBM cookie set
            index = 6;
            Marshal.InsertUshort(filetransferheader, 0x0202, ref index);
            Marshal.CopyArray(rd.Cookie, filetransferheader, 0, ref index);

            index = 0;
            try
            {
                while (index < filetransferheader.Length)
                {
                    index += rd.DirectConnection.Transfer.Send(
                        filetransferheader,
                        index,
                        filetransferheader.Length - index,
                        SocketFlags.None);
                }
            }
            catch (Exception ex)
            {
                string message = "Error negotiating file transfer:" + Environ.NewLine + ex.Message;
                throw new Exception(message);
            }

            // Open the file for writing
            try
            {
                rd.DirectConnection.DataChunk      = new byte[8192];
                rd.DirectConnection.DataStream     = (new StreamWriter(rd.DirectConnection.LocalFileName, false)).BaseStream;
                rd.DirectConnection.StreamPosition = 0;
            }
            catch (Exception)
            {
                throw new Exception("Can't open target file for writing");
            }

            // Signal the parent session that the file transfer has started
            rd.ParentSession.OnFileTransferProgress(RendezvousManager.GetKeyFromCookie(rd.Cookie),
                                                    0, rd.DirectConnection.Header.Size);

            // Start receiving data
            rd.DirectConnection.Transfer.BeginReceive(rd.DirectConnection.DataChunk, 0,
                                                      rd.DirectConnection.DataChunk.Length,
                                                      SocketFlags.None, new AsyncCallback(SendFileTransferReceive), rd);
        }