LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: rambo0808

关于socket 传送文件的问题 [困惑]

[复制链接]
 楼主| 发表于 2007-11-22 13:41:35 | 显示全部楼层
根据大家的建议,用循环的思路来做
发送端--》发送4个字节表示文件长度,  然后循环调用send,直到发送字节数为N;
接收端-》接收4个字节,知道长度后,循环调用recv,直到收到字节数为N;(recv后,每次追加方式写入文件)

但是又有新的问题出现了,出现的问题标注在代码中,我把出现问题的那部分代码贴上,请大家分析一下



  1. ---------------------------client-----------------------
  2. if(( sendbytes = send(sockfd, size ,4, 0)) == -1){
  3.         perror("send");
  4.         exit(1);
  5.    }
  6. printf("sent connection1 =  :%d\n", sendbytes );  //int bmpsize --> char size[4], 此处发送正确,bmpsize = 814502

  7.   
  8. for( i = 0; i< bmpsize ;i++){       
  9.                      
  10.     if(( sendbytes = send(sockfd, &bmpdata[i] ,1, 0)) == -1){
  11.                    perror("send");
  12.                    exit(1);
  13.             }        
  14.            }  // 在client 运行的时候,程序会在此停留很久。然后打印:send: Bad address就退出了   

  15. printf("sent connection2 = :%d\n", sendbytes );

  16. ---------------------------server--------------------------

  17.    bmpdata[0]=0xff;
  18.    bmpdata[1]=0xff;  //初始化


  19. if(( recvbytes = recv(client_fd, size, 4, 0)) == -1){
  20.         perror("recv");
  21.         exit(1);
  22.    }
  23.           
  24. bmpsize = ((size[3] & 0x000000ff) *256*256*256 ) + ((size[2] & 0x000000ff) *256*256 ) \
  25.            + ( (size[1] & 0x000000ff) *256 ) + (size[0] & 0x000000ff) *1 ;
  26.        
  27. printf(" bmpsize  is  :%d\n", bmpsize); //此处接收正确,也为client端发送的值,bmpsize = 814502


  28. i = 0;
  29.        
  30. while(1){
  31.        
  32.    if(( recvbytes = recv(client_fd, &bmpdata[i], 1, 0)) == -1){
  33.         perror("recv");
  34.         exit(1);
  35.     }
  36.       
  37.    if(i < 16)
  38.              printf("bmpdata[%d] = %d\n",i ,bmpdata[i]); //此处打印的值不为初始化值,全为0,看来在接收,但接收不正确
  39.      
  40.    i++;
  41.          
  42.    if( i == bmpsize)     //程序在这个循环中停留很久,直到client端出现错误后,才往下执行。
  43.          break;
  44.          
  45. }         
  46.    // 接收的数据全为0
  47.    printf("receiving bytes' number is  :%d\n", i);
  48.    printf("received a connection :%d\n", recvbytes );

复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-11-22 15:14:20 | 显示全部楼层
其实,做到这里我一直有一个疑问:我们通常说的数据基于TCP/IP在网络中传输,数据在应用层、传输层、网络层、数据链路层间传递。
      其中:传输层规定了TCP UDP,这两者的数据封装格式不一样的。但是我们在传递数据的时候,若socket选择了tcp或者udp,然后直接用  send、recv来发送接收数据(而不去管具体怎么封装数据包等),没有考虑任何数据封装方面的问题。那这些问题是否是我们调用的 API就自动帮我们完成了???我们只要关心要发送或者接收的数据就可以了???


上面的是问题一
建立在问题一的基础上

如果我们利用网络,向另外一个网络服务器发东西,而另外一个网络的服务器所接收的数据包要求的封装格式(非tcp、udp)和发送端TCP/IP封装的不一样,那这样的问题该如何考虑???上面的问题一中,我们没对封装格式进行操作
回复 支持 反对

使用道具 举报

发表于 2007-11-23 09:01:49 | 显示全部楼层
没细看以上的帖子, 不过个人认为楼主不应该一字节一字节的发送及接收, 我仅仅是从效率的角度来说, 而不讨论其它方面的问题. 其实修改也容易, 根据楼主的代码, 只要改成

  1. if(( sendbytes = send(sockfd, size ,4, 0)) == -1){
  2.         perror("send");
  3.         exit(1);
  4.    }
  5. printf("sent connection1 =  :%d\n", sendbytes );  //int bmpsize --> char size[4], 此处发送正确,bmpsize = 814502

  6.   
  7. for( i = 0; i< bmpsize ; i += sendbytes){       
  8.                      
  9.     if(( sendbytes = send(sockfd, &bmpdata[i] ,bmpsize - i, 0)) == -1){
  10.                    perror("send");
  11.                    exit(1);
  12.             }        
  13.            }  // 在client 运行的时候,程序会在此停留很久。然后打印:send: Bad address就退出了   

  14. printf("sent connection2 = :%d\n", sendbytes );
复制代码

即可

另外即使 send 返回 -1, 也应该检测一下 errno 是否为 EINTR, 这种情况下是中被干扰, 重试即可, 不是错误
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-11-28 22:16:10 | 显示全部楼层
谢谢大家的建议


你们的建议对我帮助很大  谢谢你们
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表