LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 798|回复: 6

高手我在linux下写了一个收文件的程序(配合windows下发文件的程序),在裁减后的主机

[复制链接]
发表于 2004-4-15 21:01:46 | 显示全部楼层 |阅读模式
我写的程序,在一般安装的linux系统中没有问题.程序的目的是:利用tcp协议,使用1333端口传文件.程序如下.现在的问题是程序能在裁减后的主机上运行,没有报错,但扫描其端口发现偶而1333端口没有打开,但有时候能打开.但不管什么情况下都无法接收文件.问了裁减系统的同志,他说开启端口应该没问题.高手我很急麻烦你们看看.




/* File: FileSvr.c */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include<dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define RECFILE_ONCE 3
int ReadDir(char* filename)
{
  struct dirent **namelist;
  struct stat fileattr;
  int n=0;
  char filename1[256];

  n=scandir(filename,&namelist,0,alphasort);
  if(n<0)
  {
    perror("scandir error");
    exit(1);
  }
  else
  {
    while(n--)
    {
      strcpy(filename1,filename);
      strcat(filename1,"/");
      strcat(filename1,namelist[n]->d_name);
      if(stat(filename1,&fileattr)==-1)
      {
        perror("can not read file's attrbute");
        exit(1);
      }
      else
      {
        if(S_ISREG(fileattr.st_mode))
        {
          printf("%s\n",namelist[n]->d_name);
        }
        else if(S_ISDIR(fileattr.st_mode))
        {
          if((strcmp(namelist[n]->d_name,".")!=0)&&(strcmp(namelist[n]->d_name,"..")!=0))
          {
            printf("%s\n",namelist[n]->d_name);
            ReadDir(filename1);
          }  
        }
      }
      free(namelist[n]);
    }
    free(namelist);
  }
  return 0;
}

int Rec_File_Socket(int client_sock_des,int address_len)   //retrun 1:restart        retrun 0:continue          return 2 :exit
{
  int read_len,k,rlen;
  int file_des;
  int *afileSize,len,alen;
  char buffer[1024],execstr[256];
  char filename[80],destpath[80];
  char *msg="ok\r\n";
  pid_t pid;
  struct sockaddr_in client_address;
  
  memset(filename,0,80);
  filename[0]='\0';
  while(strlen(filename)==0)
  {
    if((k=recv(client_sock_des,filename,80,0))==-1)
    {
      perror("recv filename error\n");
      return 1;
    }
    if(filename=='Reboot_sys_sxbug')
    {
      return 2;
    }
  }
  filename[k-2]='\0';
  len=strlen(msg);
  if (filename=="")
  {
    return 1;
  }
  else
    rlen=send(client_sock_des,msg,len,0);
  while(rlen<strlen(msg))
    rlen=send(client_sock_des,msg,len,0);
  
  memset(destpath,0,80);
  if((k=recv(client_sock_des,destpath,80,0))==-1)
  {
    perror("recv dest path error\n");
    return 1;
  }
  destpath[k-2]='\0';
     
  len=strlen(msg);
  if (filename=="")
  {
    return 1;
  }
  else
    rlen=send(client_sock_des,msg,len,0);
  while (rlen<strlen(msg))
    rlen=send(client_sock_des,msg,len,0);
   
  strcat(destpath,filename);
  if((file_des=open(destpath,O_CREAT|O_WRONLY,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH))<0)
  {
    perror("can not create file\n");
    return 1;
  }
      
  afileSize=&alen;
      
  if((k=recv(client_sock_des,afileSize,4,0))==-1)
  {
    perror("recv file size\n");
    return 1;
  }
      
  printf("status::receiving data,please wait....\n");
  k=-5;
  len=0;
      
  while(len<alen)
  {
    read_len=read(client_sock_des,buffer,sizeof(buffer));
    len+=read_len;
    write(file_des,buffer,read_len);
    k=1;
  }
  len=strlen(msg);
  rlen=send(client_sock_des,msg,len,0);
  while (rlen<strlen(msg))
    rlen=send(client_sock_des,msg,len,0);
  printf("status::the file %s has been transfered completely\n\n\n",destpath);
      
  //close(client_sock_des);
  close(file_des);
  execstr[0]='\0';
  strcat(execstr,"chmod +777 ");
  strcat(execstr,destpath);
      
  system(execstr);
  return 0;
}

int main(int argc, char **argv)
{
  int len;  
  int socket_des;
  int address_len;
  int i,j;
  int client_sock_des;
  struct sockaddr_in client_address;
  struct sockaddr_in address;
  while(1)
  {
    system("clear");
    printf("Tianxin Train Research !\n\n\n");
    socket_des = socket(AF_INET, SOCK_STREAM, 0);
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = htonl(INADDR_ANY);
    address.sin_port = htons(1333);
    address_len = sizeof(address);

    bind(socket_des, (struct sockaddr *)&address, address_len);
    listen(socket_des, 5);
    j=0;
    printf("status::wait the client to connect...\n");
   
   
    for(i = 0; i<=RECFILE_ONCE; i++)
    {   
      fflush(stdout);
      len = sizeof(client_address);
      client_sock_des = accept(socket_des,(struct sockaddr *)&client_address, &len);
      
      j=Rec_File_Socket(client_sock_des, address_len);
      close(client_sock_des);
      if(j==1)
      {
        break;
      }
   
      if(j==2)
      {
        break;
      }
    }
    close(client_sock_des);
    close(socket_des);
    if(j==2)
    {
      break;
    }
  }
}
:help
发表于 2004-4-16 20:03:51 | 显示全部楼层
在你的程序中没有错误检查,加上去看看。
 楼主| 发表于 2004-4-16 21:17:51 | 显示全部楼层
具体点可以吗?
我比较菜
发表于 2004-4-17 00:42:13 | 显示全部楼层
光看了main(),我不知道你是怎么想的,while(1)这个循环是要实现什么功能呢?这样close(socket_des)以后直接bind肯定是不行的,时间太短了,会得到一个“端口已被占用”的错误(你的程序没有错误处理,所以看不到),主要的问题就在这里。
另外,close(client_sock_des);应该是for循环的最后一句,不应该在for外面。
你的for为什么要加一个i<=RECFILE_ONCE呢?不懂。
 楼主| 发表于 2004-4-17 21:07:17 | 显示全部楼层
while(1)是因为我想让这个程序一直在运行,等待客户端的不定期连接.顺便问一下客户端可以随时断开随时连接吗?

close(socket_des)后面加一个sleep(2),可以吗?

RECFILE_ONCE是估计一次连接传文件的数目

谢谢了
发表于 2004-4-17 21:34:53 | 显示全部楼层
你说的只是一般的流程嘛,这个不需要while(1)循环,正常的处理是:

  1. ...
  2. bind(...);
  3. listen(...);
  4. for(;;){
  5.   clientfd = accept(...);
  6.   /* 可以在这里控制一次连接传文件的数目 */
  7.   close(clientfd);
  8. }
  9. close(listenfd);
复制代码

listenfd只需要打开一次,服务器就会一直监听,直到退出
每次有客户端连接就会产生一个clientfd,服务器和客户端就用这个通信
象你说的“随时断开随时连接”还要解决断点续传的问题,如果每次都传一个完整的文件就没有问题
你的服务器是单进程的,不能同时接受多个连接,这个问题一般采用的方法是:
服务器只监听listenfd,每次accept一个clientfd就fork一个子进程,由子进程和客户端通信

建议你找一本网络编程的书看看,这些问题一般在前几章都讲的
 楼主| 发表于 2004-4-18 21:49:02 | 显示全部楼层
我看看,谢谢了
但我还是不明白,为什么只有在裁减后的机器(linux)上就不能用?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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