fwrite没有在缓冲区中发送我想要的内容

时间:2014-05-20 16:01:10

标签: c file networking download fwrite

我正试图在用户键入“L”时运行LIST命令,并显示可供下载的所有文件,但是当我运行它时,键入L后,程序会打印出“eetings”。我想我没有正确使用recv(),send()或fwrite()命令,我错过了什么?当我输入

时请进一步注意
ncat 65.19.178.177 1234

在命令行中,它打印出“+ OK Greetings”,但当我在程序中输入“L”时,它会打印出“eetings”,所以我认为它是以某种方式从中获取的。

void menu()
{
 printf("L) List files\n");
 printf("D) Download a file\n");
 printf("Q) Quit\n");
}

int main(int argc, char **argv)
{
  struct sockaddr_in sa;
  int sockfd;

  sa.sin_family = AF_INET;
  sa.sin_port = htons(1234);
  inet_pton(AF_INET,"65.19.178.177", &sa.sin_addr);

  sockfd = socket(PF_INET,SOCK_STREAM, IPPROTO_TCP);
  if (sockfd == -1)
  {
   fprintf(stderr, "Can't create socket\n");
   exit(3);
  }

  int res = connect(sockfd, (struct sockaddr *)&sa, sizeof(sa));
  if (res == -1)
  {
  fprintf(stderr, "can't connect\n");
  exit(2);
  }

  char buff[1000];
  size_t rsize;
  int resultcode;

  //Get treeting from server. Expecting 220
  rsize = recv(sockfd, buff, 1000, 0);
  sscanf(buff, "%d", &resultcode);

  if (buff[0]=='+')
  {
  printf("Success\n");
  }
  else
  {
   printf("Failed: Didn't get 220\n");
  }

while(1)
{
  menu();
  char *choice = readline("Choice: ");

  switch(choice[0])
  {
   case 'l':
   case 'L':
  //Handle L case
   sprintf(buff, "LIST");
   send(sockfd, buff, strlen(buff), 0);
   while ((rsize = recv(sockfd, buff, 1000, 0)) > 0)
   {
     fwrite(buff, rsize, 1, stdout);
   }
   close(sockfd);
   break;

1 个答案:

答案 0 :(得分:1)

也许这就是正在发生的事情(我认为这就是@Martin James的意思):

在您的recv()初始版本中,您不会检查rsize的值,但如果buff[0] == '+'之后感到满意。但是,您无法通过recv()的一次通话确认您已收到完整的问候语,可能只是"+OK Gr",其余的仍在等待接收。

现在您发送命令,但在收到命令的结果之前,您将获得初始消息的其余部分,即"eetings"

你应该是这样的:

int received = 0;
int expected = strlen( "+OK Greetings" ); 

rsize = recv(sockfd, buff, 1000, 0);
if( resize <= 0 || buff[0] != '+' ) {
    // do some error handling and exit
    ..
}
received = rsize;
while( received < expected ) {
    rsize = recv(sockfd, buff+received, 1000-received, 0);
    if( resize <= 0 ) {
        // do some error handling and exit
        ..
    }
    received += rsize;
}

致电sscanf()对我没有意义,因为根据您的问题,您不会收到数值。这是对的吗?

P.S .: 如果您无法访问“真正的调试器”,则可以随时在代码中添加一些printf()语句,以查看发生的情况,如:

rsize = recv(sockfd, buff, 1000, 0);
printf( "recv() returns %d\n", rsize );