ftp客户端从服务器读取不完整的消息

时间:2014-03-18 19:55:56

标签: c sockets ftp

这是我的代码简单的ftp客户端我可以连接到服务器登录但我的程序从服务器读取随机不完整的消息有时它们是完整的但有时它只读取几个字节而且我不知道该怎么做请帮助我

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>

#define BUF_SIZE 5000

int main()
{
  struct addrinfo hints;
  struct addrinfo *result, *rp;
  int my_socket, passive_socket, sock, len, m = 0, bytes;
  char buf[BUF_SIZE], i[BUF_SIZE];

  memset(&hints, 0, sizeof(struct addrinfo));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_protocol = 0;

  if ((sock = getaddrinfo("ftp.linux.cz", "ftp", &hints, &result)) != 0)
  {
    fprintf(stderr, "%s\n", gai_strerror(sock));
    exit(EXIT_FAILURE);
  }

  for (rp = result; rp != NULL ; rp = rp->ai_next)
  {
    if ((my_socket = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol))
        == -1)
      continue;
    if (connect(my_socket, rp->ai_addr, rp->ai_addrlen) != -1)
      break;
    close(my_socket);
  }

  freeaddrinfo(result);

  read(my_socket, buf, BUF_SIZE);
  printf("%s", buf);

  len = strlen("USER anonymous\r\n");
  write(my_socket, "USER anonymous\r\n", len);

  read(my_socket, buf, BUF_SIZE);
  printf("%s", buf);

  len = strlen("PASS secret\r\n");
  write(my_socket, "PASS secret\r\n", len);

  read(my_socket, buf, BUF_SIZE);
  printf("%d\n", bytes);
  for (int n = 0; n < bytes; n++)
    printf("%c", buf[n]);

  len = strlen("EPSV\r\n");
  write(my_socket, "EPSV\r\n", len);

  read(my_socket, buf, BUF_SIZE);
  //printf( "%s", buf );  

  for (int n = 39; n > 0; n++)
  {
    if (buf[n] >= 48 && buf[n] <= 57)
    {
      i[m] = buf[n];
      m++;
    }
    else
    {
      i[m] = '\0';
      n = -1;
    }
  }

  printf("%s\n", i);

#if 0
  if ((sock = getaddrinfo("ftp.fit.vutbr.cz", i, &hints, &result)) != 0)
  {
    fprintf(stderr, "%s\n", gai_strerror(sock));
    exit(EXIT_FAILURE);
  }

  for (rp = result; rp != NULL ; rp = rp->ai_next)
  {
    if ((passive_socket = socket(rp->ai_family, rp->ai_socktype,
        rp->ai_protocol)) == -1)
      continue;
    if (connect(passive_socket, rp->ai_addr, rp->ai_addrlen) != -1)
      break;
    close(passive_socket);
  }

  read(passive_socket, buf, BUF_SIZE);
  printf("%s", buf);

  len = strlen("NLST\r\n");
  write(my_socket, "NLST\r\n", len);

  read(passive_socket, buf, BUF_SIZE);
  printf("%s", buf);
#endif

  return 0;
}

1 个答案:

答案 0 :(得分:2)

您不能假设读取一次读取整个响应,它可以读取更少,它可以读取BUF_SIZE个字节,但在一次调用期间不能读取更多。

你的程序显然没有干净的解析器。你应该对你正在阅读的内容作出适当的反应,这可能是一条信息性的消息,一个警告,一个错误或其他什么。

我可以给你的最好建议是查看State Machine Pattern,如果你想为FTP协议推出自己的解析器,并转到Lexical Analyzerproperly built parsers以便这样做。

通过这种方式,您最终将能够构建功能强大且功能强大的网络应用程序。