Windows 7 Pro、x64 システムで実行する CFtpServer の最初のサンプル プログラムを取得しようとしていました。私が見たものを信じずに、ブッシュの周りを何度も叩いた後、私は問題を次の単純なプログラムに落とし込みました。
#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 コマンドに応答するために使用する文字列に似た文字列を書き込みます。何か問題が発生するまで、1 秒に 1 回、文字列を送信し続けます。
私のシステムでは、nc.exe コマンドを使用してこの「サーバー」に接続すると、いくつかの文字列が表示され、ソケットが閉じます (「サーバー」によって出力されるエラーは 10053 です)。
Windows ファイアウォールを無効にすると、nc コマンドを実行したままにしておく限り、文字列が表示されます。
私は 2 つの異なるバリエーションを見てきましたが、違いの原因はわかりません: 文字列 '227' を送信したときに停止することがあり、その後 '229' で停止し始めました。送信されるテキストに敏感であるように見えます。