全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2438
推到 Plurk!
推到 Facebook!

用winsock 寫ftp client,accept無法觸發

缺席
luckfox
一般會員


發表:34
回覆:40
積分:24
註冊:2002-10-15

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-12-30 12:54:24 IP:211.75.xxx.xxx 未訂閱
我嚐試用winsocket寫個ftp client,目前有個問題 我下ftp的list指令,這是用sniffer看的狀況,server已經有送資料到data socket http://tw.photo.yahoo.com/luckfox0927/ab19/p1555.jpg  可是並沒有觸發我的accept的event,這是怎麼回事,我哪裡搞錯了嗎,希望各為賢達幫我看一下...    //---------------------------------------------------------------------------    #include  #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" USELIB("ws2_32.lib"); TForm1 *Form1; int ReadLine(int hSocket,char *sLine); //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { if(WSAStartup(0x101,&wd)!=0) { StatusBar1->SimpleText="Can't Load winsock.dll"; bWSALoad=false; } else { bWSALoad=true; Init(); } } //--------------------------------------------------------------------------- void __fastcall TForm1::Init() { LPHOSTENT lpHost; char *pAddr; gethostname(HostName,StrLen); Memo3->Lines->Add("取得主機名稱 " AnsiString(HostName)); lpHost=gethostbyname(HostName); memcpy(&MyInAddr,lpHost->h_addr_list[0],sizeof(struct in_addr)); pAddr=(char *)&MyInAddr; Memo3->Lines->Add("取得本機IP=" AnsiString(inet_ntoa(MyInAddr))); _getcwd(LocalDir,StrLen); ComboBox1->Text=AnsiString(LocalDir); last_port=FTP_DATA_BOTTOM; bConnect=false; } void __fastcall TForm1::Button1Click(TObject *Sender) { LPHOSTENT lpHost; in_addr addr; AnsiString asMsg; lpHost=gethostbyname(Edit1->Text.c_str()); memcpy(&ServInAddr,lpHost->h_addr_list[0],sizeof(in_addr)); Label4->Caption=AnsiString(inet_ntoa(ServInAddr)); lpHost=gethostbyaddr((char *)&ServInAddr,sizeof(ServInAddr),AF_INET); hCSocket=socket(AF_INET,SOCK_STREAM,0); ServAddr.sin_family=AF_INET; ServAddr.sin_port=htons(FTP_PORT); ServAddr.sin_addr=ServInAddr; if((connect(hCSocket,(sockaddr *)&ServAddr,sizeof(ServAddr)))==SOCKET_ERROR) { StatusBar1->SimpleText="Can't connect to " AnsiString(inet_ntoa(ServInAddr)); } else Memo3->Lines->Add("connect to " AnsiString(inet_ntoa(ServInAddr))); //取得welcome資料 asMsg=GetFtpReply(hCSocket); Memo3->Lines->Add(asMsg); //送出user資料 asMsg="USER " Edit2->Text; SendFtpCmd(hCSocket,asMsg); asMsg=GetFtpReply(hCSocket); Memo3->Lines->Add(asMsg); //送出passwd asMsg="PASS " Edit3->Text; SendFtpCmd(hCSocket,asMsg); asMsg=GetFtpReply(hCSocket); Memo3->Lines->Add(asMsg); //取得Server的系統型態 SendFtpCmd(hCSocket,AnsiString("SYST")); asMsg=GetFtpReply(hCSocket); Memo3->Lines->Add(asMsg); //取得remote server 的目前目錄 asMsg=GetRemoteDir(hCSocket); ComboBox2->Text=asMsg; //設定傳輸mode=ascii SendFtpCmd(hCSocket,AnsiString("TYPE A")); asMsg=GetFtpReply(hCSocket); Memo3->Lines->Add(asMsg); //建立data transfer socket if(SendDataPort()==0) asMsg="建立Data transfer socket成功"; else asMsg="無法建立Data transfer socket"; Memo3->Lines->Add(asMsg); //取得remote server目前目錄的檔案清單 asMsg= AnsiString("LIST ") ComboBox2->Text; SendFtpCmd(hCSocket,asMsg); asMsg=GetFtpReply(hCSocket); Memo3->Lines->Add(asMsg); } //--------------------------------------------------------------------------- int __fastcall TForm1::SendFtpCmd(int hSocket,AnsiString asCmd) { char sStr[255]; int len; asCmd=asCmd "\r\n"; len=asCmd.Length(); memcpy(sStr,asCmd.c_str(),len); send(hSocket,sStr,asCmd.Length(),0); return 0; } AnsiString __fastcall TForm1::GetFtpReply(int hSocket) { char buffer[255]; AnsiString asMsg; while(1) { if(ReadLine(hSocket,buffer)>0) { asMsg=asMsg AnsiString(buffer); if(buffer[0]>='0' && buffer[0]<='9' && buffer[3]==' ')//最後一行msg break; } } return asMsg; } int __fastcall TForm1::ReadLine(int hSocket,char *sLine) { int iRet,index; char buf[2]; bool CTL_flag=true; index=0; while(CTL_flag) if((iRet=recv(hSocket,buf,1,0))==1) {//檢查是否為\n否則其餘則讀入 *(sLine index)=buf[0]; if(buf[0]=='\n') CTL_flag=false; index ; } else if(iRet==0) {//讀到檔尾了 CTL_flag=false; } else {//有問題 } *(sLine index)='\0'; return index; } void __fastcall TForm1::CloseConn(int hSocket) { // WSAAsyncSelect(hSocket, } AnsiString __fastcall TForm1::GetRemoteDir(int hSocket) { AnsiString asMsg; char sStr[255]; int i; SendFtpCmd(hSocket,"PWD"); asMsg=GetFtpReply(hSocket); for(i=5;iLines->Add("socket() error!"); return -1; } DataAddr.sin_family=AF_INET; DataAddr.sin_addr=MyInAddr; pAddr=(char *)&DataAddr.sin_addr; while(1) { if(last_port >FTP_DATA_TOP) last_port=FTP_DATA_BOTTOM; DataAddr.sin_port=htons(last_port); Memo3->Lines->Add("嘗試建立Data Socket IP=" AnsiString(inet_ntoa(MyInAddr)) "Port=" IntToStr(last_port)); last_port ; if(bind(hASocket,(sockaddr *)&DataAddr,sizeof(DataAddr))==SOCKET_ERROR) { if((iErrorCode=WSAGetLastError())==WSAEADDRINUSE) continue; else { Memo3->Lines->Add("bind() error! error code=" IntToStr(iErrorCode)); closesocket(hASocket); return -1; } } else break; } //設定ACCEPT和RECVICE的非同步事件處理函示 if(WSAAsyncSelect(hASocket,btnAccept->Handle,WM_KEYDOWN,FD_ACCEPT)==SOCKET_ERROR) { Memo3->Lines->Add("設定ACCEPT 非同步處理函式失敗"); } if(WSAAsyncSelect(hASocket,btnRecv->Handle,WM_KEYDOWN,FD_READ|FD_WRITE|FD_CLOSE)==SOCKET_ERROR) { Memo3->Lines->Add("設定READ,WRITE,CLOSE 非同步處理函式失敗"); } if(listen(hASocket,1)==SOCKET_ERROR) { Memo3->Lines->Add("Listen() error!"); closesocket(hASocket); return -1; } len=sizeof(DataAddr); //取得socket的address & port資料,確認可用 getsockname(hASocket,(sockaddr *)&DataAddr,&len); pAddr=(char *)&(DataAddr.sin_addr); pPort=(char *)&(DataAddr.sin_port); wsprintf(sCmdStr,"PORT %d,%d,%d,%d,%d,%d",pAddr[0],pAddr[1],pAddr[2],pAddr[3], pPort[0],pPort[1]); SendFtpCmd(hCSocket,AnsiString(sCmdStr)); asMsg=GetFtpReply(hCSocket); Memo3->Lines->Add(asMsg); return 0; } //--------------------------------------------------------------------------- void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) { if(bWSALoad==true) { WSACleanup(); bWSALoad=false; } } //--------------------------------------------------------------------------- void __fastcall TForm1::BitBtn1Click(TObject *Sender) { if(bWSALoad==true) { WSACleanup(); bWSALoad=false; } } //--------------------------------------------------------------------------- void __fastcall TForm1::btnRecvMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { while (1); } //--------------------------------------------------------------------------- void __fastcall TForm1::btnAcceptKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { if((hDSocket=accept(hASocket,(sockaddr *)&FromAddr,&iFromLen))<0) { Memo3->Lines->Add("accept() error!"); } else Memo3->Lines->Add("accept() success!"); } //------
luckfox
一般會員


發表:34
回覆:40
積分:24
註冊:2002-10-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2002-12-30 13:57:43 IP:211.75.xxx.xxx 未訂閱
已將此程式upload至問題程式上載區,使用bcb 6.0
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#3 引用回覆 回覆 發表時間:2002-12-30 15:18:55 IP:61.221.xxx.xxx 未訂閱
引言: 已將此程式upload至問題程式上載區,使用bcb 6.0
luckfox 你好: 我已經試過你的程式碼~~希望有幾個問題能夠釐清 < class="code"> (1)這個連結 http://tw.photo.yahoo.com/luckfox0927/ab19/p1555.jpg 會產生以下的錯誤 You don't have permission to access /luckfox0927/ab19/p1555.jpg on this server. (> --
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
luckfox
一般會員


發表:34
回覆:40
積分:24
註冊:2002-10-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2002-12-30 15:54:32 IP:211.75.xxx.xxx 未訂閱
0.謝謝你的答覆 1.已經將圖檔放置圖檔存放區了 2.這三個warning我想並不會影響程式的運作    304行,因為都無法accept,如何receive ,所以此行不影響    316行,或可改成if((hDSocket=accept(hASocket,(sockaddr *) &FromAddr,&iFromLen))!=SOCKET_ERROR)    3.我的問題是,當我connect到ftp Server(port 21)後,下list命令(取得ftp server的file list),server已經有傳資料,但是我的data socket並沒有收到accept ,意即當server從data port(port 20)傳資料過來後,我的line 316行if((hDSocket=accept(hASocket,(sockaddr *)&FromAddr,&iFromLen))<0)應該會被執行到 ,因為我在line 249 if(WSAAsyncSelect(hASocket,btnAccept->Handle,WM_KEYDOWN,FD_ACCEPT)==SOCKET_ERROR) 並沒有問題 ,然而事實上,在line 316行下 break point,並不會break到
skcc
中階會員


發表:36
回覆:96
積分:88
註冊:2002-08-28

發送簡訊給我
#5 引用回覆 回覆 發表時間:2002-12-30 16:27:22 IP:203.198.xxx.xxx 未訂閱
引言: 0.謝謝你的答覆 1.已經將圖檔放置圖檔存放區了 2.這三個warning我想並不會影響程式的運作 304行,因為都無法accept,如何receive ,所以此行不影響 316行,或可改成if((hDSocket=accept(hASocket,(sockaddr *) &FromAddr,&iFromLen))!=SOCKET_ERROR) 3.我的問題是,當我connect到ftp Server(port 21)後,下list命令(取得ftp server的file list),server已經有傳資料,但是我的data socket並沒有收到accept ,意即當server從data port(port 20)傳資料過來後,我的line 316行if((hDSocket=accept(hASocket,(sockaddr *)&FromAddr,&iFromLen))<0)應該會被執行到 ,因為我在line 249 if(WSAAsyncSelect(hASocket,btnAccept->Handle,WM_KEYDOWN,FD_ACCEPT)==SOCKET_ERROR) 並沒有問題 ,然而事實上,在line 316行下 break point,並不會break到
請先確認你的 FTP Server 是 Passive 還是 Active 模式? Anthony Lee
luckfox
一般會員


發表:34
回覆:40
積分:24
註冊:2002-10-15

發送簡訊給我
#6 引用回覆 回覆 發表時間:2002-12-30 17:14:01 IP:211.75.xxx.xxx 未訂閱
我不太清楚你的意思,對ftp client而言,他可以提出passive或非passive的要求(我是採用非passive),似乎和server無關 passive->由ftp server提出Server Data port 非passive ->由ftp client提出client的Data port (見圖檔上傳區) 目前已經知道我有成功的送出port命令,並且可以下list命令,server也送到正確的client data port(見圖檔上傳區),(我程式給的client data port是40000)然而我的accept就是無法觸發.....
系統時間:2024-03-29 9:07:13
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!