2013-07-06 70 views
0

我有我希望的一个问题是一个错误,因为我有点新来的Linux C.ç3G文件传输客户端/服务器的Linux

我有一个服务器,发送文件到客户端。该代码完全适用于有线连接,每次都能100%成功。但是,当我尝试通过-65dB(强)的3G USB连接运行相同的代码时,客户端通常只会接收文件的前1或2千字节。 (请原谅的语法错误,不会让我的空间正常)

 // CLIENT CODE 

     char* fs_name = "/target/to/send"; 
     char sdbuf[LENGTH]; // Send buffer, LENGTH == 512 
     printf("Sending %s to the Client... \n", fs_name); 
     FILE *fs = fopen(fs_name, "r"); 
     if(fs == NULL) 
     { 
      fprintf(stderr, "ERROR: File %s not found on server. (errno = %d)\n", fs_name, errno); 
      exit(1); 
     } 

     bzero(sdbuf, LENGTH); 
     int fs_block_sz; 
     while((fs_block_sz = fread(sdbuf, sizeof(char), LENGTH, fs))>0) 
     { 
      if(send(client, sdbuf, fs_block_sz, 0) < 0) 
      { 
       fprintf(stderr, "ERROR: Failed to send file %s. (errno = %d)\n", fs_name, errno); 
       exit(1); 
      } 
      bzero(sdbuf, LENGTH); 
     } 
     printf("File send Success\n"); 



      // SERVER CODE 

     char* fr_name = "/home/file/to/save"; 

     FILE *fr = fopen(fr_name, "a"); 

     if(fr == NULL) 

      printf("File %s Cannot be opened.\n", fr_name); 

     else 
     { 
       // zero out bytes 
      bzero(revbuf, LENGTH); 

      int fr_block_sz = 0; 

      while((fr_block_sz = recv(sd, revbuf, LENGTH, 0)) > 0) //LENGTH == 512 
      { 
      int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr); 

       if(write_sz < fr_block_sz) 
      { 
        error("File write failed.\n"); 
       } 
      bzero(revbuf, LENGTH); 
      if (fr_block_sz == 0 || fr_block_sz != 512) 
      { 
      break; 
      } 
     } 

       // error checking 
     if(fr_block_sz < 0) 
       { 
     if (errno == EAGAIN) 
     { 
      printf("recv() timed out.\n"); 
     } 
     else 
     { 
      fprintf(stderr, "recv() failed due to errno = %d\n", errno); 
     } 


      fclose(fr); 

如果有任何人可以对我在做什么错了,我会最欣赏一些启发。谢谢阅读。

编辑:服务器是Ubuntu 10.04,客户端是Arch Linux ARM,发送的文件类型是ARM二进制文件。

+0

为什么客户端,有什么回报RECV在周期的退出?如果rect返回<0打印fprintf(stderr,“recv返回错误:%s \ n”,sterror(errno))? – fghj

+0

如果我正确理解你的意思,客户端不会收到错误。客户端简单地保存文件,就好像它是完整的东西,并没有提供错误信息,服务器也没有。然后我必须手动调整该文件的大小以查找xfer失败。它有时可以工作,但可能有15%的时间。也许我需要以1000字节块发送文件,然后在客户端重新组装它或其他东西?不幸的是,我注意到3G与电线有点不同。 – 4r4r4r

+0

你谈论某种魔术。如果您有TCP连接,并且从一边发送100MB文件块在另一边您收到或100MB或连接断开。可能你使用UDP? – fghj

回答

0

我认为你的主要问题是在你的代码标记为服务器,但真正看起来是客户端。你假设recv将在每个recv上获得全部512个字节,但事实并非如此 - 你可以并且会得到短的读取。如果你没有完全读取LENGTH(即512),稍微低于读取循环。这就解释了为什么你的pgm在几千字节之后退出。

while ((fr_block_sz = recv(sd, revbuf, LENGTH, 0)) > 0) //LENGTH == 512 
    { 
     int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr); 

     if (write_sz < fr_block_sz) 
     { 
      error("File write failed.\n"); 
     } 

     bzero(revbuf, LENGTH); 

     if (fr_block_sz == 0 || fr_block_sz != 512) 
     { 
      break; 
     } 

    } 

你想要更多的东西是这样的:(根据您的代码服务器)仅收到1000字节

while ((fr_block_sz = recv(sd, revbuf, LENGTH, 0)) > 0) //LENGTH == 512 
    { 
     if (fr_block_sz < 0) 
      if (errno == EAGAIN) 
       continue; 
      else 
       error; 

     if (fr_block_sz == 0) 
      break; //done 

     int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr); 

     if (write_sz < fr_block_sz) 
     { 
      error("File write failed.\n"); 
     } 

     bzero(revbuf, LENGTH); 
    } 
+0

谢谢鸭子,但我不明白。我有服务器代码与客户端混淆,我的服务器真的是客户端,你发布的代码是我的服务器应该看起来像什么样的客户端? – 4r4r4r

+0

服务器/客户端/无论如何。这在这里并不重要。以上代码直接来自您发布的内容。我会发布一些我认为应该解决您的主要问题的伪代码。 – Duck

+0

Thanks Duck,我能够根据您的伪代码(在服务器保持不变的情况下)在客户端进行这些更改,并且使得我的成功率为5/7,其他传输成功率达到了4K字节。 2次失败的尝试可能是由于3G连接。奇怪它如何在电线上正常工作。我想知道3G编程技术是否与传统的有线编程不同。 – 4r4r4r

相关问题