2013-02-27 105 views
0

我試圖讓CFtpServer的第一個例子程序在Windows 7 Pro x64系統上運行。拐彎抹角經過多次毆打,不相信我所看到的,我得到了這個問題下面的這個簡單的程序:爲什麼Windows 7防火牆阻止PASV FTP連接?

#include <iostream> 
using namespace std; 

#include <windows.h> 
#include <winsock2.h> 
#include <ws2tcpip.h> 
#include <stdio.h> 


#define die(code) { cerr << "die at " << __FILE__ << " " << __LINE__ << " "; exit(code); } 

int main(int argc, char **argv) 
{ 
    short port = 21; 

    if (argc == 2) { 
     port = atoi(argv[1]); 
    } 

    WSADATA WSAData; 
    if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0) 
     die(1); 

    SOCKET ls = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//!!! proto 0 in ftpdmin! 
    if (ls == INVALID_SOCKET) die(1); 

    struct sockaddr_in sin; 
    sin.sin_family = AF_INET; 
    sin.sin_addr.s_addr = INADDR_ANY; 
    sin.sin_port = htons(port); 

    if (bind(ls, (struct sockaddr *) &sin, sizeof(struct sockaddr_in)) 
      == SOCKET_ERROR) die(2); 

    if (listen(ls, 1) == SOCKET_ERROR) //!!! backlog 1 in ftpdmin! 
     die(3); 


    // wait for connect, transmit till error 
    SOCKET ts; 
    for(;;) { 
     ts = accept(ls, NULL, NULL); 
     if (ts == INVALID_SOCKET) die(5); 

     // now write some things to that socket. 
     int i=0; 
     for(;;) { 
      char buf[256]; 
      sprintf(buf, "%d Testing...\r\n",i+224); 
      if (send(ts, buf, strlen(buf), 0) < 0) { 
       DWORD err = WSAGetLastError(); 
       cerr << "send failed with " << err << endl; 
       break; 
      } 
      Sleep(1000); 
      i = (i+1)%10; 
     } 

     Sleep(1000); 
     closesocket(ts); 
    } 
} 

該程序打開指定的插座,它偵聽連接。當它獲得連接時,它會繼續編寫與FTP服務器可能用來響應PASV命令的字符串類似的字符串。它會一直傳輸字符串,每秒一次,直到出現問題。

在我的系統上,使用nc.exe命令連接到這個「服務器」,我看到一些字符串,然後套接字將關閉(由'服務器'打印的錯誤是10053)。

如果我禁用了Windows防火牆,只要我關心離開nc命令就可以看到字符串。

我見過兩種不同的變化,我不知道是什麼導致了這種差異:有時它會在傳輸字符串'227'時停止,後來它開始死於'229'。它讓每一個對發送的文本都敏感的表象。

回答

2

經過3天的打擊我的頭,我有一個答案:窗口KB2754804。這是一個自2011年以來MS已知的錯誤。在引用的知識庫文章中有一個修補程序,但它似乎不適用於我的測試,所以我必須採取禁用有狀態FTP防火牆的備用路由。

我終於到了知識庫文章,從this SO入口。