Linux:cpp编写本地文件客户端与服务器

文章目录

      • 一、客户端
      • 二、服务端
      • 三、用法
      • 四、UNP
      • 五、代码

一、客户端

功能:

  • 通过get获取服务器的文件并下载到客户端本地自定义文件夹中
  • 通过list查看服务器的文件
    核心代码:
#include 
#include 
#include	"unp.h"
void ftp_cli(FILE *fp, int sockfd);
ssize_t Readline2(int fd, void *ptr, size_t maxlen);
int main(int argc, char **argv)
{
	int					sockfd;
	struct sockaddr_in	servaddr;

	if (argc != 2)
		err_quit("usage: tcpcli ");

	sockfd = Socket(AF_INET, SOCK_STREAM, 0);

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(21000);
	Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);

	Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));

	ftp_cli(stdin, sockfd);		/* do it all */

	exit(0);
}


void ftp_cli(FILE *fp, int sockfd)
{

	char sendline[MAXLINE], recvline[MAXLINE];
	char cmd [MAXLINE];
	char wdpath[200];
	if(getcwd(wdpath,200)==NULL)return ;
	strcat(wdpath,"/clidir");

	for ( ; ; )
	{
	    fprintf(stderr, "myftpclient-->");
        if (Fgets(sendline, MAXLINE, fp) == NULL) return;
			//else fputs(sendline,stdout);
		strcpy(cmd,sendline);
		//int i;
		//for(i=0;i<strlen(sendline);i++)
		//fprintf(stderr,"%d\n",(int)(sendline[i]));
		char * pcmd=strtok(cmd," \n");
		if(strcmp(pcmd,"dir")==0||strcmp(pcmd,"ls")==0||strcmp(pcmd,"list")==0)
		{
            Writen(sockfd, sendline, strlen(sendline));
		    if (Readline2(sockfd, recvline, MAXLINE) == 0)
				err_quit("str_cli: server terminated prematurely");
            int lines=atoi(recvline);
            int i;
			for(i=0;i<lines;i++)
			{
			    Readline2(sockfd, recvline, MAXLINE);
			    fprintf(stderr,recvline);
			}
        }
        else if(strcmp(pcmd,"get")==0)
		{
            Writen(sockfd, sendline, strlen(sendline));
		    if (Readline2(sockfd, recvline, MAXLINE) == 0)
				err_quit("str_cli: server terminated prematurely");
            int bytes=atoi(recvline);
            fprintf(stderr, "file length = %d.\n",bytes);
            int left=bytes;
            FILE *fp=0;

            if(left>0)
            {
                char filename[100];
                strcpy(filename,wdpath);
                strcat(filename,"/");
                strcat(filename, strtok(NULL," \n"));

                if((fp=fopen(filename,"wb"))==NULL)
                {
                    fprintf(stderr,"failed open file %s",filename);
                    return;
                }
                fprintf(stderr, "file create: %s.\n",filename);
            }

            while(left>MAXLINE)
            {
                Readn(sockfd, recvline, MAXLINE);
                left-=MAXLINE;
                fwrite(recvline,MAXLINE,1,fp);
            }
            if(left<=MAXLINE)
            {
                Readn(sockfd, recvline, left);
			    //fprintf(stderr,recvline);
			    fwrite(recvline,left,1,fp);
            }
            fprintf(stderr, "file writen done.\n");
            fclose(fp);
        }
        else if(strcmp(pcmd,"quit")==0)
		{
		    fprintf(stderr, "See you!.\n");
		    return;
		}
       	else if(strcmp(pcmd,"delete")==0){
		    Writen(sockfd,sendline,strlen(sendline));

            if (Readline2(sockfd, recvline, MAXLINE) == 0){
				err_quit("str_cli: server terminated prematurely");
            }else
                fprintf(stderr,"file %s delete successfully.\n",recvline);

        }else if(strcmp(pcmd,"put") == 0){

            Writen(sockfd, sendline, strlen(sendline));
            char filename[100];
            strcpy(filename,wdpath);
            strcat(filename,"/");

            strcat(filename,strtok(NULL," \n"));
            FILE *fp = 0;
            if((fp = fopen(filename,"rb")) == NULL){
                fprintf(stderr,"failed open file %s",filename);
                return;
            }
            fprintf(stderr,"open file %s.\n",filename);

            long filelen;

            fseek(fp,0,SEEK_END);
            filelen = ftell(fp);
            rewind(fp);
            char flen[7];
            sprintf(flen,"%d\n",(int)filelen);
            fprintf(stderr,"filesize %s\n",flen);

            Writen(sockfd,flen,strlen(flen));
            fprintf(stderr,"sent filesize=%s",flen);
            long left = filelen;

            while(left > MAXLINE){

                    fread(sendline,MAXLINE,1,fp);
                    Writen(sockfd,sendline,MAXLINE);
                    left -= MAXLINE;
            }

            if(left <= MAXLINE){

                fread(sendline,left,1,fp);
                Writen(sockfd,sendline,left);

            }

            fprintf(stderr,"file send done.\n");

            fclose(fp);


        }else{
            fprintf(stderr, "usage:cmd [args].\ncmd=\tdir\tls\tget\tquit\n");
        }


	}
}

ssize_t
readline(int fd, void *vptr, size_t maxlen)
{
	ssize_t	n, rc;
	char	c, *ptr;

	ptr = vptr;
	for (n = 1; n < maxlen; n++) {
again:
		if ( (rc = read(fd, &c, 1)) == 1) {
			*ptr++ = c;
			if (c == '\n')
				break;	/* newline is stored, like fgets() */
		} else if (rc == 0) {
			*ptr = 0;
			return(n - 1);	/* EOF, n - 1 bytes were read */
		} else {
			if (errno == EINTR)
				goto again;
			return(-1);		/* error, errno set by read() */
		}
	}

	*ptr = 0;	/* null terminate like fgets() */
	return(n);
}
/* end readline */

ssize_t
Readline2(int fd, void *ptr, size_t maxlen)
{
	ssize_t		n;

	if ( (n = readline(fd, ptr, maxlen)) < 0)
		err_sys("readline error");
	return(n);
}

二、服务端

功能:

  • 监听来自客户端的请求,服务器里面的文件都存放在服务器本地自定义文件夹中
    核心代码:
#include	"unp.h"
#include 
#include 
#include 
#include 
void ftpserv(int sockfd);
void sig_chld(int signo);
ssize_t Readline2(int fd, void *ptr, size_t maxlen);
int main(int argc, char **argv)
{
	int					listenfd, connfd;
	pid_t				childpid;
	socklen_t			clilen;
	struct sockaddr_in	cliaddr, servaddr;
	void				sig_chld(int);

	listenfd = Socket(AF_INET, SOCK_STREAM, 0);

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family      = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port        = htons(21000);

	Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

	Listen(listenfd, LISTENQ);

	Signal(SIGCHLD, sig_chld);	/* must call waitpid() */

	for ( ; ; )
	{
		clilen = sizeof(cliaddr);
		if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0)
		{
			if (errno == EINTR)
				continue;		/* back to for() */
			else
				err_sys("accept error");
		}

		if ( (childpid = Fork()) == 0)
		{	/* child process */
			Close(listenfd);	/* close listening socket */
			ftpserv(connfd);	/* process the request */
			exit(0);
		}
		Close(connfd);			/* parent closes connected socket */
	}
}



void ftpserv(int sockfd)
{
	ssize_t		n;
	char		buf[MAXLINE];
	char		sendline[MAXLINE],recvline[MAXLINE];
	char wdpath[200];
	if(getcwd(wdpath,200)==NULL)return ;
	strcat(wdpath,"/user");

	char dirname[1000];
	char dirlen[7];

	DIR *pdir;
	struct dirent *pent;
	if ((pdir = opendir(wdpath)) == NULL)
	{
		fprintf(stderr, "open dir failed.\n");
		return;
	}


again:
	while ( (n = Readline2(sockfd, buf, MAXLINE)) > 0)
	{
	    //Writen(sockfd, buf, n);
        fprintf(stderr,"n=%d\nbuf=%s",n,buf);
	    char * cmd=strtok(buf," \n");

	    if( strcmp(cmd,"dir") ==0 || strcmp(cmd,"ls")==0 || strcmp(cmd,"list")==0)
	    {
	        char * pdirname=dirname;
	        int lines=0;

            while (1)
            {
                    pent = readdir(pdir);
                    if (pent == NULL) break;
                   // fprintf(stderr, "%5d %s\n",pent->d_ino, pent->d_name);
                    strcpy(pdirname,pent->d_name);
                    strcat(pdirname,"\r\n");
                    fprintf(stderr, "%d %s",strlen(pdirname), pdirname);
                    lines++;
                    pdirname+=strlen(pent->d_name)+2;

            }
            *pdirname=0;
            sprintf(dirlen,"%d\n",lines);
            fprintf(stderr,"lines %d\n",lines);
            Writen(sockfd, dirlen, strlen(dirlen));
            Writen(sockfd,dirname,strlen(dirname));
            rewinddir(pdir);
	    }
	    else if(strcmp(cmd,"get")==0)
	    {

	        char filename[100];
            strcpy(filename,wdpath);
            strcat(filename,"/");
            strcat(filename, strtok(NULL," \n"));
            FILE *fp=0;

            if((fp=fopen(filename,"rb"))==NULL)
            {
                fprintf(stderr,"failed open file %s",filename);
                return;
            }
            fprintf(stderr, "open file %s.\n",filename);

            long filelen;
            fseek(fp,0,SEEK_END);
            filelen=ftell(fp);
            rewind(fp);
            char flen[7];
            sprintf(flen,"%d\n",(int)filelen);
            fprintf(stderr,"filesize %s\n",flen);
            Writen(sockfd, flen, strlen(flen));
            fprintf(stderr, "sent filesize=%s",flen);

            long left=filelen;
            while(left>MAXLINE)
            {
                fread(sendline,MAXLINE,1,fp);
                Writen(sockfd, sendline, MAXLINE);
                left-=MAXLINE;
            }
            if(left<=MAXLINE)
            {
                fread(sendline,left,1,fp);
                Writen(sockfd, sendline, left);
            }

            fprintf(stderr, "file sent done.\n");
            fclose(fp);




        } /**/
	    else if(strcmp(cmd,"put")==0){
            if(Readline2(sockfd,recvline,MAXLINE) == 0){
                err_quit("str_cli: client terminated prematurely");
            }
            int bytes = atoi(recvline);
            fprintf(stderr,"file length = %d.\n",bytes);
            int left = bytes;
            FILE *fp = 0;
            if(left > 0){
                char filename[100];
                strcpy(filename,wdpath);
                strcat(filename,"/");
                strcat(filename,strtok(NULL," \n"));
                if((fp = fopen(filename,"wb")) == NULL){
                    fprintf(stderr,"failed open file %s",filename);
                    return;
                }

                fprintf(stderr,"file create: %s.\n",filename);

            }

            while(left > MAXLINE){
                    Readn(sockfd,recvline,MAXLINE);
                    left -= MAXLINE;
                    fwrite(recvline,MAXLINE,1,fp);
            }
            if(left <= MAXLINE){

                Readn(sockfd,recvline,left);
                fwrite(recvline,left,1,fp);
            }

            fprintf(stderr,"file writen done.\n");
            fclose(fp);




        }
	    else if(strcmp(cmd,"delete")==0){
            char filename[100];
            char name[30];
            strcpy(filename,wdpath);
            strcat(filename,"/");

            strcat(filename,strtok(NULL," \n"));
            printf("filename is %s\n",filename);
            sprintf(name,"%s\n",filename);
            Writen(sockfd,name,strlen(name));
            if(remove(filename) == 0){
                fprintf(stderr,"file delete successfully.\n");

            }else{
                fprintf(stderr,"file don't exist.\n");
            }


        }
	    else
	    {}


        if (n < 0 && errno == EINTR)
            goto again;
        else if (n < 0)
            err_sys(" read error");
        //closedir(pdir);

	}
	fprintf(stderr,"n=%d\nbuf=%s",n,buf);


}

void sig_chld(int signo)
{
	pid_t	pid;
	int		stat;

	while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0)
		printf("child %d terminated\n", pid);
	return;
}

ssize_t
readline(int fd, void *vptr, size_t maxlen)
{
	ssize_t	n, rc;
	char	c, *ptr;

	ptr = vptr;
	for (n = 1; n < maxlen; n++) {
again:
		if ( (rc = read(fd, &c, 1)) == 1) {
			*ptr++ = c;
			if (c == '\n')
				break;	/* newline is stored, like fgets() */
		} else if (rc == 0) {
			*ptr = 0;
			return(n - 1);	/* EOF, n - 1 bytes were read */
		} else {
			if (errno == EINTR)
				goto again;
			return(-1);		/* error, errno set by read() */
		}
	}

	*ptr = 0;	/* null terminate like fgets() */
	return(n);
}
/* end readline */

ssize_t
Readline2(int fd, void *ptr, size_t maxlen)
{
	ssize_t		n;

	if ( (n = readline(fd, ptr, maxlen)) < 0)
		err_sys("readline error");
	return(n);
}

三、用法

服务器部分:

  1. 执行make clean与make
  2. 运行命令 ./ftps

客户端部分:

  1. 执行make clean与make
  2. 运行命令 ./ftpc 127.0.0.1

注意:./ftps要先于./ftpc 127.0.0.1运行

四、UNP

客户端与服务器的编译都是依赖了libunp.a静态库,因此,在make之前最好在自己的环境里面编译得到新的libunp.a,然后替换文件夹里面旧的静态链接库,再make。

  1. 解压unpv13e.tar.gz
  2. 进入目录执行
./configure
cd lib   //进入lib目录
make     //执行make命令
  1. 把新生成的libunp.a替换旧的libunp.a

五、代码

下载链接

你可能感兴趣的:(C/C++,Linux,makefile,linux,文本服务器,文件服务器,c++)