Beispiel #1
0
        // === SendFileData() (TYPE_REQ_DOWNLOAD) === //
        private void SendFileData(ReqDownLoadPack reqPack) // 요청한 파일 데이터를 보낸다. (다운로드)
        {
            string path     = rootPath + reqPack.Path;
            Pack   flagPack = new Pack();

            using (Stream fileStream = new FileStream(path, FileMode.Open)) // 전송요청 받은 파일을 연다.
            {
                byte[] buffer    = new byte[1024 * 1024];                   // 한번에 읽어들일 바이트수 (1MB)
                int    totalRead = 0;                                       // 파일로부터 읽어들은 총 크기

                Console.WriteLine(" === 다운로드 시작 : {0} === ", ((IPEndPoint)client.Client.RemoteEndPoint).ToString());

                while (true)
                {
                    flagPack = (Pack)serializer.Deserialize(clientStream); // 전송을 계속할지 여부를 클라이언트 요청 받으면서 진행
                    if (flagPack.Flag == CONSTANTS.FLAG_NO)
                    {
                        break;
                    }

                    int read = fileStream.Read(buffer, 0, (1024 * 1024)); // 파일로부터 데이터 읽는다.
                    totalRead += read;
                    SendDataPack resPack = new SendDataPack()
                    {
                        Last = CONSTANTS.NOT_LAST,
                        Data = new byte[read]
                    };

                    Array.Copy(buffer, 0, resPack.Data, 0, read); // 파일로부터 읽은 데이터 보낼 DATA[]로 복사

                    if (totalRead >= fileStream.Length)           // 총 읽은크기가 파일의 크기 이상일때 (다 읽었을때)
                    {
                        resPack.Last = CONSTANTS.LAST;            // 전송의 끝을알림
                        serializer.Serialize(clientStream, resPack);
                        break;
                    }

                    serializer.Serialize(clientStream, resPack);
                }

                Console.WriteLine();

                if (totalRead == fileStream.Length)
                {
                    Console.WriteLine("<->다운로드 성공 : {0}", ((IPEndPoint)client.Client.RemoteEndPoint).ToString());
                    Console.WriteLine(" ({0} / {1}) ", totalRead, fileStream.Length);
                }
                else
                {
                    Console.WriteLine("<!>다운로드 중지 : {0} ", ((IPEndPoint)client.Client.RemoteEndPoint).ToString());
                    Console.WriteLine(" ({0} / {1}) ", totalRead, fileStream.Length);
                }
            }
        }
Beispiel #2
0
        // === ReceiveFileData() (TYPE_REQ_UPLOAD) === //
        private void ReceiveFileData(ReqUpLoadPack reqPack)                        // 요청한 파일 데이터를 받는다. (업로드)
        {
            fileStream = new FileStream(rootPath + reqPack.Path, FileMode.Create); // 요청경로의 파일스트림
            SendDataPack resPack   = new SendDataPack();                           // 파일 데이터를 계속해서 담는 인스턴스
            ulong        totalSize = reqPack.FileSize;                             // 원래 파일크기
            long         recvSize  = 0;                                            // 받은 크기

            Pack flagPack = new Pack()                                             // 파일전송을 유지여부를 결정하기 위한 Pack 계속받아서 판별한다.
            {
                Flag = CONSTANTS.FLAG_YES
            };

            serializer.Serialize(clientStream, flagPack); // 시작신호 보낸다.
            Console.WriteLine("<->업로드 시작 : {0} ", ((IPEndPoint)client.Client.RemoteEndPoint).ToString());

            while ((resPack = (SendDataPack)serializer.Deserialize(clientStream)) != null) // 받을 Pack이 없을때까지 반복
            {
                fileStream.Write(resPack.Data, 0, resPack.Data.Length);                    // 받은 Pack의 DATA[]을 파일로쓴다.
                recvSize += resPack.Data.Length;                                           // 받은크기 늘린다.

                if (resPack.Last == CONSTANTS.LAST)                                        // LAST == LAST는 파일의 끝을의미
                {
                    break;
                }
            }

            Console.WriteLine();

            if ((ulong)recvSize == totalSize) // 받은사이즈 == 원래파일크기
            {
                Console.WriteLine("<->업로드 성공 : {0} ", ((IPEndPoint)client.Client.RemoteEndPoint).ToString());
                Console.WriteLine(" ({0} / {1}) ", recvSize, totalSize);
            }
            else
            {
                Console.WriteLine("<!>업로드 중지 : {0} ", ((IPEndPoint)client.Client.RemoteEndPoint).ToString());
                Console.WriteLine(" ({0} / {1}) ", recvSize, totalSize);
            }

            fileStream.Close();
        }
Beispiel #3
0
        private async void btn_Up_Click(object sender, EventArgs e) // 올리기 버튼을 누른경우 업로드를 해준다.
        {
            BinaryFormatter serializer = new BinaryFormatter();
            Pack            flagPack   = new Pack();
            FileInfo        fileInfo;
            string          fileName = "";
            string          filePath = "";

            if (!runUp)                 // runUp = true 이면 이미 업로드가 진행중이라는 뜻이다.
            {
                if (selectedPath == "") // 선택한 디렉토리가 없으면 리턴 //
                {
                    MessageBox.Show("업로드할 폴더를 선택해주세요", "알림");
                    return;
                }

                if (upDialog.ShowDialog() == DialogResult.OK) // OpenFileDialog를 띄우고 //
                {
                    runUp       = true;
                    btn_Up.Text = "취소";                                // '올리기'버튼을 '취소'로 만든다.

                    int bsIndex = upDialog.FileName.LastIndexOf("\\"); // 선택한 파일 정보를 가져온다 //
                    fileName = upDialog.FileName.Substring(bsIndex + 1, upDialog.FileName.Length - bsIndex - 1);
                    filePath = selectedPath + "\\" + fileName;
                    fileInfo = new FileInfo(upDialog.FileName);
                }
                else
                {
                    return;
                }

                ReqUpLoadPack reqPack = new ReqUpLoadPack // 요청을 보낸다 //
                {
                    Path     = filePath,
                    FileSize = (ulong)fileInfo.Length
                };
                TcpClient     client = fileConnect();
                NetworkStream stream = client.GetStream();
                serializer.Serialize(stream, reqPack);           // <!> 요청을 보낸다 //

                flagPack = (Pack)serializer.Deserialize(stream); // 서버에서 보내지말라하면 메소드 나감 //
                if (flagPack.Flag == CONSTANTS.FLAG_NO)
                {
                    return;
                }

                await Task.Run(() => // 비동기로 처리하는 이유 : 업로드 도중 다른작업을 가능하게 해준다. (비동기로 하지않으면 이 메소드가 반환되기전까지 창이 굳는다.)
                {
                    progressBar1.Value = 0;

                    using (Stream fileStream = new FileStream(upDialog.FileName, FileMode.Open))
                    {
                        byte[] buffer = new byte[1024 * 1024]; // 읽어서 보낼 데이터 저장 배열
                        long readSize = 0;                     // 읽어서(보낸) 크기 저장

                        while (true)
                        {
                            int read             = fileStream.Read(buffer, 0, (1024 * 1024));
                            readSize            += read; // 읽은 크기늘린다.
                            SendDataPack resPack = new SendDataPack()
                            {
                                Data = new byte[read],
                                Last = CONSTANTS.NOT_LAST
                            };
                            // 퍼센트바, 진행률 레이블 갱신
                            double per         = readSize / (double)fileStream.Length * 100;
                            progressBar1.Value = (int)per;
                            lbl_Size.Text      = string.Format("{0} /\t{1}", readSize, fileStream.Length);
                            lbl_Percent.Text   = string.Format("{0:F2} %", per);
                            Update();

                            Array.Copy(buffer, 0, resPack.Data, 0, read); // 읽은 배열 보낼 Pack에 복사
                            if (readSize >= fileStream.Length || !runUp)  // 원본 파일 크기만큼 읽었다면 마지막 Pack을 보내기위해 표시한다.
                            {
                                resPack.Last = CONSTANTS.LAST;            // ㄴ 또는 '취소' 버튼을 눌러서 중단해도 마지막 표시를한다. ( 취소하면 runUp이 false가 된다.)
                            }
                            serializer.Serialize(stream, resPack);

                            if (resPack.Last == CONSTANTS.LAST) // 보낸 Pack이 마지막이면 반복문 종료
                            {
                                break;
                            }
                        }
                    }

                    if (runUp) // 이건 정상적으로 업로드했을 경우다.
                    {
                        lbl_State.Text = "올리기 완료 : " + fileName;
                        runUp          = false;
                    }
                    else if (!runUp) // 이건 취소버튼을 눌렀을 경우이다.
                    {
                        MessageBox.Show("작업취소", "알림");
                        lbl_State.Text = "올리기가 취소 되었습니다.";
                    }

                    btn_Up.Text = "올리기";        // 다시 업로드 버튼으로 만든다.
                    stream.Close(); client.Close();
                });
            }
            else if (runUp)
            {
                runUp = false; // 이러면 다음반복에서 멈춘다.
            }
        }
Beispiel #4
0
        private bool go   = true;   // 다운로드를 계속 진행할지 여부를 체크한다.

        public async void DownLoad(ListViewItem selectedItem, string downPath, string selectedPath, TcpClient client)
        {
            BinaryFormatter serializer = new BinaryFormatter();
            NetworkStream   stream     = client.GetStream();

            string          selectFile = selectedItem.SubItems[0].Text;              // 다운로드 받을 파일이름
            ulong           totalSize  = ulong.Parse(selectedItem.SubItems[4].Text); // 다운로드 받을 파일 크기
            string          filePath   = selectedPath + "\\" + selectFile;           // 현재 선택된 경로를 포함한 전체경로
            ReqDownLoadPack reqPack    = new ReqDownLoadPack                         // 요청보낼 Pack 인스턴스
            {
                PackType = CONSTANTS.TYPE_REQ_DOWNLOAD,
                Path     = filePath,
            };

            // 운로드 요청 보냈다 //
            serializer.Serialize(stream, reqPack);

            // 파일 받을 준비 //

            ulong        recvSize = 0;       // 현재까지 다운로드 받은 크기
            SendDataPack resPack  = new SendDataPack();
            Pack         flagPack = new Pack // 서버에 다운로드를 계속할지 여부를 알려주는 요청 Pack이다. FALG를 CONSTANTS.FLAG_NO 보내면 다운로드를 중단할것이다.
            {
                PackType = CONSTANTS.TYPE_BASIC,
                Flag     = CONSTANTS.FLAG_YES
            };

            serializer.Serialize(stream, flagPack); // 시작신호를 보낸다.

            await Task.Run(() =>
            {
                try
                {
                    using (FileStream fileStream = new FileStream(downPath + "\\" + selectFile, FileMode.Create)) // 다운로드 경로에 파일이름으로 새파일 생성
                    {
                        while ((resPack = (SendDataPack)serializer.Deserialize(stream)) != null)                  // 파일서버에서 보내는 Pack을 계속받는다.
                        {
                            fileStream.Write(resPack.Data, 0, resPack.Data.Length);
                            recvSize += (ulong)resPack.Data.Length;

                            double per = recvSize / (double)totalSize * 100;

                            progressBar1.Value = (int)per;
                            lbl_FileName.Text  = string.Format("다운로드 파일 : {0}", selectFile);
                            lbl_State.Text     = string.Format("{0} / \t {1}", recvSize, totalSize);
                            lbl_Percent.Text   = string.Format("{0:F2} %", per);

                            if (resPack.Last == CONSTANTS.LAST) // 보낸 Pack이 마지막이면 반복문을 나간다.
                            {
                                break;
                            }
                            else if (!go)                          // 이 경우는 사용자가 취소버튼을 누른경우이다.
                            {
                                flagPack.Flag = CONSTANTS.FLAG_NO; // 서버에 다운로드 중지요청을 보낸다.
                                serializer.Serialize(stream, flagPack);
                                break;
                            }

                            serializer.Serialize(stream, flagPack); // 신호를 보낸다.
                        }
                    }

                    if (go) // 반복문을 빠져나오고 go == true 이면 정상 다운로드 완료
                    {
                        lbl_State.Text  = lbl_FileName.Text = string.Format("다운로드 완료 : {0}", selectFile);
                        btn_Cancle.Text = "확인";
                        done            = true;
                    }
                    else // 취소를했다. 바로 종료한다.
                    {
                        this.Close();
                    }
                }
                catch (IOException e)
                {
                    if (e.HResult == -2147024864)
                    {
                        MessageBox.Show("지정된 경로를 엑세스할 수 없습니다.", "오류");
                    }

                    done            = true;
                    btn_Cancle.Text = "닫기";
                }
                finally
                {
                    stream.Close();
                    client.Close();
                }
            });
        }