線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2088
推到 Plurk!
推到 Facebook!

網路傳檔時想要臨時暫停或停止的問題

答題得分者是:Vicen
haman
中階會員


發表:46
回覆:137
積分:56
註冊:2005-03-10

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-09-08 17:49:15 IP:211.76.xxx.xxx 未訂閱
關於傳檔的部份我是參考RaynorPao大大的範例 http://delphi.ktop.com.tw/topic.php?topic_id=25912 http://delphi.ktop.com.tw/topic.php?topic_id=25913 做的,但是想做到"傳輸中斷"的功能,卻又卡在for迴圈跳出的問題 參考了站上的一些文章,多是用執行緒解決, 而RaynorPao大大在 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=24198 這篇所說的方法試過後卻會發生一個狀況, ServerSocket1ClientRead的事件會在傳檔的for迴圈跑完後才發生, 但我的client早已送出中斷傳輸的要求了,這個問題該怎麼解決呢?    下面是client端的片段
void __fastcall TForm3::ReceiveFile(PkgData *Files)
{
        String StrSoc = Files->SocID;
        String StrDes = Files->DesID;
        String FileName;
        String FileStatus;
        String FileWait;
        FileName = Files->NetMSG;
        if(FileName == "OK")
                Form1->SendFile();
        else
        if(FileName == "NO")
                ShowMessage("對方已取消傳輸");
        else
        {
                FileStatus = FileName.SubString(FileName.Pos(":") 1,FileName.Length());
                FileName = FileName.SubString(0,FileName.Pos(":")-1);
                int Code;
                if(FileStatus == "START")
                {
                        String StrTmp = StrSoc;
                        StrTmp = StrTmp   "傳送";
                        StrTmp = StrTmp   FileName;
                        StrTmp = StrTmp   "給您,您是否要接收?";
                        Code = Application->MessageBoxA(StrTmp.c_str(),"接收檔案",1);
                        if(Code ==1)
                        {
                                strcpy(Files->NetMSG,"OK");
                                gmsFile->Size=Files->FileSize;
                                gmsFile->Position = 0;
                                Form3->Show();
                                StringGrid->Cells[1][1] = StrSoc;
                                StringGrid->Cells[0][1] = "傳送中";
                                StringGrid->Cells[2][1] = FileName;
                                StringGrid->Cells[3][1] = IntToStr(Files->FileSize);
                                StringGrid->Cells[4][1] = IntToStr(Files->ThisSize);
                                StringGrid->Cells[7][1] = "0";
                                int Per = StringGrid->Cells[4][1].ToInt() * 100 / StringGrid->Cells[3][1].ToInt();
                                StringGrid->Cells[8][1] = IntToStr(Per)   "%";
                                gmsFile->Write(Files->FileData, Files->ThisSize);
                        }
                        else
                                strcpy(Files->NetMSG,"NO");
                        Files->ConCode = 5;
                        strcpy(Files->SocID,Files->DesID);
                        strcpy(Files->DesID,StrSoc.c_str());
                        Form1->ClientSocket->Socket->SendBuf(Files,sizeof(PkgData));
                }
                else
                if(FileStatus == "CONTINUE")
                {
                        StringGrid->Cells[4][1] = IntToStr(StringGrid->Cells[4][1].ToInt()   Files->ThisSize);
                        int Per = StringGrid->Cells[4][1].ToInt() * 100 / StringGrid->Cells[3][1].ToInt();
                        StringGrid->Cells[8][1] = IntToStr(Per)   "%";
                        StringGrid->Cells[7][1] = IntToStr(StringGrid->Cells[7][1].ToInt() 1);      //pkg count
                        ProgressBar->Position = StringGrid->Cells[8][1].SubString(0,StringGrid->Cells[8][1].Pos("%")-1).ToInt();
                        gmsFile->Write(Files->FileData, Files->ThisSize);
                        if(Form1->ReceiveWait)//要求暫停
                        {
                                strcpy(Files->NetMSG,"WAIT");
                                //在這裡就送出暫停的要求了
                                Form1->ClientSocket->Socket->SendBuf(Files,sizeof(PkgData));
                                FileWait = "END";
                        }
                }
                else
                if(FileStatus == "END")
                        FileWait = "END";
                FileName = "\\"   FileName;
                Form3->EndFile(FileName,FileWait,Files);
        }
}
//---------------------------------------------------------------------------
void __fastcall TForm3::ButtonClick(TObject *Sender)
{
        //這裡是暫停傳輸的button
                Form1->ReceiveWait = true;
}
[/cdoe]    下面是server端的片段
[cdoe]
void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,
      TCustomWinSocket *Socket)
{
        String StrTmp = "ControlCode :";
        Socket->ReceiveBuf(RcvPkg,sizeof(PkgData));            StrTmp = StrTmp   IntToStr(RcvPkg->ConCode);
        Memo1->Lines->Add(StrTmp);
        StrTmp = "SourceID :";
        StrTmp = StrTmp   RcvPkg->SocID;
        Memo1->Lines->Add(StrTmp);
        StrTmp = "DestinationID :";
        StrTmp = StrTmp   RcvPkg->DesID;
        Memo1->Lines->Add(StrTmp);
        StrTmp = "Message :";
        StrTmp = StrTmp   RcvPkg->NetMSG;
        Memo1->Lines->Add(StrTmp);
        if(RcvPkg->ConCode == 5)
        {
                if(strcmp(RcvPkg->NetMSG,"WAIT") != 0)
                        RcvFile();
                else
                        FileWait = true;//在這裡設定是否要中止傳送
        }
}
//---------------------------------------------------------------------------
void TForm1::SendFile(char *RcvUsr)
{
        TMemoryStream *msFile=new TMemoryStream;
        PkgData *SndPkg = new PkgData;
        msFile->LoadFromFile(OpenDialog->FileName);
        int i=0;
        int block=(msFile->Size%MAX_FSIZE==0)?
        msFile->Size/MAX_FSIZE: msFile->Size/MAX_FSIZE 1;  //傳送次數
        String FileName;
        for(i=1; iFileName)  ":";
                SndPkg->ConCode = 5;
                strcpy(SndPkg->SocID,"SYSTEM");
                strcpy(SndPkg->DesID,RcvUsr);
                strcpy(SndPkg->NetMSG,FileName.c_str());
                if(i==block-1)
                        FileName = FileName   "END";
                else
                        FileName = FileName   "CONTINUE";
                strcpy(SndPkg->NetMSG, FileName.c_str());
                SndPkg->PkgCount = i;
                SndPkg->FileSize = msFile->Size;
                SndPkg->ThisSize =((i 1)*MAX_FSIZE>msFile->Size)?
                        msFile->Size-i*MAX_FSIZE: MAX_FSIZE;
                msFile->Position=i*MAX_FSIZE;
                msFile->Read(SndPkg->FileData,SndPkg->ThisSize);
                if(!FileWait)
                        ServerSocket1->Socket->Connections[0]->SendBuf(SndPkg,sizeof(PkgData));
                else
                        break;//在這裡跳出傳送的動作
                Sleep(10);
        }
        Memo1->Lines->Add("傳輸完成");
        delete msFile;
        delete SndPkg;
}
Vicen
高階會員


發表:13
回覆:145
積分:151
註冊:2005-03-14

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-09-09 09:43:49 IP:221.226.xxx.xxx 未訂閱
其实非阻塞方式使用FOR循环发送文件需要使用有个发送间隔时间,这就像你在FOR循环中用SLEEP(10)一样,但其实这种情况下难以保证在任何网络状况下都能将文件完整送出,    我不是很懂 BCB,所以只能提些建议,请haman兄勿见怪。 看以下你的代码: < class="code"> for(i=1; iFileName) ":"; SndPkg->ConCode = 5; strcpy(SndPkg->SocID,"SYSTEM"); strcpy(SndPkg->DesID,RcvUsr); strcpy(SndPkg->NetMSG,FileName.c_str()); if(i==block-1) FileName = FileName "END"; else FileName = FileName "CONTINUE"; strcpy(SndPkg->NetMSG, FileName.c_str()); SndPkg->PkgCount = i; SndPkg->FileSize = msFile->Size; SndPkg->ThisSize =((i 1)*MAX_FSIZE>msFile->Size)? msFile->Size-i*MAX_FSIZE: MAX_FSIZE; msFile->Position=i*MAX_FSIZE; msFile->Read(SndPkg->FileData,SndPkg->ThisSize); //这里是我送我送,管你收到不。 >>> > } 其实不论网络状况如何,这种传输都不安全,而且效率很低,传输一个小文件获取看不出影响,但如果是一个>
haman
中階會員


發表:46
回覆:137
積分:56
註冊:2005-03-10

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-09-16 20:20:17 IP:211.76.xxx.xxx 未訂閱
這個問題解決了@@" 我是用rogan321大大在這篇 http://delphi.ktop.com.tw/topic.php?topic_id=69095 提到的Application->ProcessMessages();的方式解決的
        for(i=1; iFileName)  ":";
                SndPkg->ConCode = 5;
                strcpy(SndPkg->SocID,"SYSTEM");
                strcpy(SndPkg->DesID,RcvUsr);
                strcpy(SndPkg->NetMSG,FileName.c_str());
                if(i==block-1)
                        FileName = FileName   "END";
                else
                        FileName = FileName   "CONTINUE";
                strcpy(SndPkg->NetMSG, FileName.c_str());
                SndPkg->PkgCount = i;
                SndPkg->FileSize = msFile->Size;
                SndPkg->ThisSize =((i 1)*MAX_FSIZE>msFile->Size)?
                        msFile->Size-i*MAX_FSIZE: MAX_FSIZE;
                msFile->Position=i*MAX_FSIZE;
                msFile->Read(SndPkg->FileData,SndPkg->ThisSize);
                Application->ProcessMessages();                 //讓cpu去處理其他事
                if(!FileWait)
                        ServerSocket1->Socket->Connections[0]->SendBuf(SndPkg,sizeof(PkgData));
                else
                        break;
                Sleep(10);
        }
唉,懂的少,寫起程式來還真是累丫>"<
系統時間:2024-04-25 12:52:01
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!