send()とputs()は一緒に混合されます(CでFTPサーバをプログラム)

StackOverflow https://stackoverflow.com//questions/25038909

  •  21-12-2019
  •  | 
  •  

質問

私はFTPサーバーをCで作成しています。クライアント側でFileZillaを使用しています。これまでのコードには、ハンドシェイク部分のみが含まれています。

私が持っている問題は、ターミナルに印刷する文字列がfilezillaに送信されることです。 私の質問は、これら2つを別々に保つことができます、私はいくつかのことを試しましたが、それらのどれも正しい結果を与えませんでした。

これは私のコードの一部ですが、私の質問のためにこれは役に立つ部分です:

while (FOREVER){
    addr_size = sizeof their_addr;

    newfd = accept(listener, (struct sockaddr*) &their_addr, &addr_size);
    if (newfd == -1){
        perror("accept");
        continue;
    }
    if ((send(newfd, "220 JEDI FTP is ready", 50, 0)) <= 0)
        perror("error sending");

    puts("connection established");
    puts("waiting for user & connection");
  while (!login){
        // username
        if (!user){
            if ((recv(newfd, buffer, BUFFCON, 0)) <= 0){
                puts("error receiving username");

            }
            else{

                if (strstr(buffer, "USER") != NULL){

                    if (strstr(buffer, name) != NULL){

                        send(newfd, "331 password required", 50, 0);
                        puts("username correct");

                        user = 1;
                    }
                    else{
                        puts("username incorrect");
                        send(newfd, "430 username incorrect", 50, 0);
                    }//else
                }//if
            }//else
        }//if user
.

とこれはfilezillaの出力です:

  • ステータス:ADRES BEPALEN VAN LOCALHOST
  • ステータス:Verbinden Met [:: 1]:21 ...
  • ステータス:動き出しAangemaakt、Welkomstbericht Afwachten ...
  • Antworord:220 Jedi FTPの準備ができている
  • Commando:ユーザーヨーダ
  • Antwoord:接続確立
  • FOUT:Kan Niet Verbinden Met Server

「331パスワードが必要な」を送信する代わりに「接続確立」

を送信します。

これで私を助けることができることを願って、たくさんありがとう。

役に立ちましたか?

解決

問題は、lensendパラメータが大きすぎることです。 sendには、ヌル終端文字列の概念はありません。それはバイトの生のシーケンスでのみ機能します。そのため、Call send(newfd, "220 JEDI FTP is ready", 50, 0)は文字列"220 JEDI FTP is ready"を送信し、次にそれ以降のメモリに入ってくるものは何でもします。技術的には、これは未定義の動作です。文字通りが発生する可能性があります(通常はSegFault)。あなたの場合、定数のリテラル文字列は通常メモリに順番に保存されるため、sendは指定された文字列を読み、次にそれ以降の文字列を読み取っています。

あなたがやりたいことのみ正確な文字列を送信すること(つまり、各コマンドの後にCR-LFシーケンス\r\nを必要とします)。もう少し、それほどない。 SOのような文字列を送信するためのsends関数を実装できます。

ssize_t sends(int fd, const char *str)
{
    size_t len = strlen(str);
    return send(fd, str, len, 0);
}
.

TCPパケットは文字列のサイズを指定しているため、送信されていないデータはNULL-TERKINATERを含みます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top