⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileserver.c

📁 类似于FTP的远程文件拷贝程序。
💻 C
字号:
#include "filecp.h"struct hostent *hp;int sock_c=-1,sock_ca=-1,sock_d=-1;struct sockaddr_in sock_addr;void exit_fuc(void){}void sig_kill(int signo){  if(sock_d!=-1)close(sock_d);  if(sock_ca!=-1)close(sock_ca);  if(sock_c!=-1)close(sock_c);}void sig_child(int signo){  int stat;pid_t pid;  while((pid=waitpid(-1,&stat,WNOHANG))>0){;}}int port_init (struct sockaddr_in *ddsin, short dport){  int ds;  ds = socket (AF_INET, SOCK_STREAM, 0);  if (ds < 0)  {    printf("the request for portd socket failed !!!\n");    exit (3);  }  ddsin->sin_family = AF_INET;  ddsin->sin_port = htons (dport);  bcopy(hp->h_addr,&(ddsin->sin_addr),hp->h_length);  if (bind (ds, (struct sockaddr *) ddsin, sizeof (struct sockaddr_in)) < 0)  {    printf("the server bind portd failed !!!\n");    close (ds);    exit (4);  }  if (listen (ds, 5) < 0)  {    printf("Server listen portd failed\n");    exit (5);  }  return ds;};int testfile (char *filename){  int fd1;  fd1 = open (filename, O_RDONLY);  if (fd1 < 0)    return SFA;  else  {    close (fd1);    return SFE;  }}int getfile (char *filename){  int fromlen,dns;  char buf[1024];  register int infile,c;  struct sockaddr_in sin;  fromlen=sizeof(sin);  if ((dns = accept (sock_d, (struct sockaddr *) &sin, &fromlen)) < 0)  {    perror ("server:accept portd failed");    exit (-1);  }  infile =open (filename, O_WRONLY | O_CREAT | O_TRUNC,	  S_IRWXU | S_IRWXG | S_IROTH);  if (infile <= 0)  {     //perror ("打开文件出错\n");     close(dns);     return -1;  }  while((c=readn (dns, buf, sizeof (buf)))>0)  {    if(write(infile,buf,c)!=c)    {      //写错误      exit(-1);    }  }  close(infile);  close(dns);  exit(0);}int outfile (char *filename){  int j = 0, k = 0;  int outfile,c,ds=0,dns, fromlen;  struct sockaddr_in sin;  char buf[1024];  if ((dns = accept (ds, (struct sockaddr *) &sin, &fromlen)) < 0)    {      perror ("server:accept portd failed");      exit (6);    }  outfile = open (filename, O_RDONLY);  if (outfile <= 0)    {      perror ("打开文件出错\n");      return -1;    }  c = read (outfile, buf, sizeof (buf));  if (c < 0)    {      close (dns);      close (outfile);      perror ("error");      exit (0);    }  else    {      while (c > 0)	{	  if ((k = writen (dns, buf, c)) < 0)	    {	      close (dns);	      close (outfile);	      perror ("error0");	      exit (0);	    }	  j += k;	  c = read (outfile, buf, sizeof (buf));	}      close (dns);      close (outfile);      return SERVER_OK;    }}int shellexec (char *cmdstring, int n){  char cmdstring1[60];  int i;  for (i=0;i<n;i++) cmdstring1[i]=(*cmdstring++);  strcat (cmdstring1, " > /tmp/tmp.txt");  if (system (cmdstring1) == 0)    return SCS;  else    return SCF;}void on_connect(int ns){  int k,fromlen,c;  char cmdstring[60];  struct sockaddr_in sin;  struct packet_data packetdata;  if (read(ns, &packetdata, sizeof(packetdata)) !=sizeof(packetdata))  {    perror ("server:reading portc failed");    exit(-1);  }  sock_d=port_init(&sin,0);fromlen=sizeof(sin);  getsockname(sock_d,(struct sockaddr*)&sin,&fromlen);  packetdata.port_data = htons (sin.sin_port);//数据端口  switch (packetdata.packettype)  {    case PUT:      switch (packetdata.stat)      {        case STAT0:/*起动查询过程,返回查询结果给客户进程,并继续监听PORTC */          packetdata.stat = testfile (packetdata.body.copyfile.server_file_name);          packetdata.stat |= STAT1;          if (write (ns, &packetdata, sizeof (packetdata)) < 0)          {            perror ("write the socket error!!!\n");            exit (0);          }          if (read (ns, &packetdata, sizeof (packetdata)) < 0)          {            perror ("second read the socket error!!!\n");            exit (0);          }          //sleep(1);          if(packetdata.stat==(STAT2 | CLIENT_OK))            packetdata.stat = getfile(packetdata.body.copyfile.server_file_name);          break;        default:          break;      }      break;      case GET:/*对于客户端要求从服务器拷出文件的情况 */        switch (packetdata.stat)/*查询服务器端是否有指定的文件,将结果返回给客户端,并起动监听端口 */        {	  case STAT0:	    packetdata.stat = STAT1|testfile (packetdata.body.copyfile.server_file_name);	    if (write (ns, &packetdata, sizeof (packetdata)) < 0)	    {	      perror ("write the socket error!!!\n");	      exit (0);	    }	    if (read (ns, &packetdata, sizeof (packetdata)) < 0)	    {	      perror ("second read the socket error!!!\n");	      exit (0);	    }	  case STAT2 | CLIENT_OK:	    packetdata.stat = outfile (packetdata.body.copyfile.server_file_name);	    break;	  default:	    break;	}	break;      case SHELLC:	switch (packetdata.stat)	{	  case STAT0:	    c = strlen (packetdata.body.commandline.cmdstring);	    packetdata.stat =	    shellexec (packetdata.body.commandline.cmdstring, c);	    packetdata.stat |= STAT1;	    if (write (ns, &packetdata, sizeof (packetdata)) < 0)	    {	      perror ("write the socket error!!!\n");	      exit (0);	    }	    if (read (ns, &packetdata, sizeof (packetdata)) < 0)	    {	      perror ("second read the socket error!!!\n");	      exit (0);	    }	  case STAT2 | CLIENT_OK:	    packetdata.stat = outfile ("/tmp/tmp.txt");	    break;	  default:	    break;	}	break;  }  exit(0);}int main(int argc,char *argv[]){  int ns,ifork,fromlen;  struct sockaddr_in sin;  char name[20];  if((ifork=fork())<0)  {    //err:不能打开进程    printf(">>can't fork\n");    exit(-1);  }  else if(ifork>0)  {    //关闭主进程    exit(0);  }  atexit(exit_fuc);  gethostname(name,18);  hp = gethostbyname (name);  if(hp==NULL)  {    printf("err:can't find eth\n");  }  else  {    bcopy( hp->h_addr,&sock_addr.sin_addr, hp->h_length);  }  sock_c = port_init (&sin, PORTC);  signal(SIGCHLD,sig_child);  signal(SIGKILL,sig_kill);  printf("fileserver start...\n");  while (1)  {    if ((ns = accept (sock_c,(struct sockaddr *) &sin, &fromlen)) < 0)    {      //perror ("server:accept portc failed");    }    if((ifork=fork())==0)    {      //子进程      close(sock_c);      sock_c=-1;      sock_ca=ns;      on_connect(ns);    }    else if(ifork==-1)    {    }    close(ns);  }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -