亚洲欧美日韩综合系列在线_91精品人妻一区二区_欧美大肥婆一级特大AA片_九色91视频免费观看_亚洲综合国产精品_av中文字幕在线不卡_久久精品色综合网_看黄色视频的软件_无卡无码高清中文字幕码2024_亚洲欧美日韩天堂网

Linux 下c語(yǔ)言ftp服務(wù)器簡(jiǎn)單實(shí)現(xiàn)

來(lái)源:Lstri 發(fā)布時(shí)間:2018-11-21 15:26:27 閱讀量:1229

原來(lái)的程序沒(méi)有注釋?zhuān)罱@段時(shí)間在學(xué)習(xí)網(wǎng)絡(luò)編程這塊,就在網(wǎng)上找了個(gè)程序來(lái)學(xué)習(xí),第一次找的程序下載下來(lái)后,編譯沒(méi)通過(guò),剛接觸網(wǎng)絡(luò),哪可能去排錯(cuò)誤,況且代碼那么長(zhǎng),一下讓我退了下來(lái),還是等以后有了基礎(chǔ),再回過(guò)頭看它!


     然后就找到了這個(gè)程序,拿下來(lái)運(yùn)行了下,然后讀了讀,自己加上了注釋?zhuān)M芙o跟我一樣的新手一點(diǎn)幫助吧,里面有不恰當(dāng)?shù)牡胤秸?qǐng)指出哈。


//client.c

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <netinet/in.h>

#include <fcntl.h>

 

#define N 256

 

typedef struct sockaddr SA;

 

void commd_help();

void commd_exit();

void commd_ls(struct sockaddr_in, char *);

void commd_get(struct sockaddr_in , char *);

void commd_put(struct sockaddr_in , char *);

 

int main(int argc, char *argv[])

{

    char commd[N];

    struct sockaddr_in addr;

    int len;

    bzero(&addr, sizeof(addr));     //將&addr中的前sizeof(addr)字節(jié)置為0,包括'\0'

    addr.sin_family = AF_INET;      //AF_INET代表TCP/IP協(xié)議

    addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //將點(diǎn)間隔地址轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)順序

    addr.sin_port = htons(8989);    //轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)順序

    len = sizeof(addr);

 

    while(1)

    {

        printf("ftp>");

        bzero(commd,N);

        //fgets函數(shù)從stdin流中讀取N-1個(gè)字符放入commd中

        if(fgets(commd,N,stdin) == NULL)

        {

            printf("Fgets Error!\n");

            return -1;

        }

 

        commd[strlen(commd)-1]='\0';    //fgets函數(shù)讀取的最后一個(gè)字符為換行符,此處將其替換為'\0'

 

        printf("Input Command Is [ %s ]\n",commd);

 

        if(strncmp(commd,"help",4) == 0) //比較兩個(gè)字符串前4個(gè)字節(jié),若相等則返回0

        {

            commd_help();

        }else if(strncmp(commd, "exit",4) == 0)

        {

            commd_exit();

            exit(0);   //結(jié)束進(jìn)程

        }else if(strncmp(commd, "ls" , 2) == 0)

        {

            commd_ls(addr, commd);

        }else if(strncmp(commd, "get" , 3) == 0)

        {

            commd_get(addr, commd);

        }else if(strncmp(commd, "put", 3) ==0 )

        {

            commd_put(addr, commd);

        }else

        {

            printf("Command Is Error!Please Try Again!\n");

        }

 

    }

    return 0;

}

 

void commd_help()

{

 

    printf("\n=------------------- Welcome to Use the Ftp ----------------=\n");

    printf("|                                                           |\n");

    printf("|  help : Display All Command for the Server                |\n");

    printf("|                                                           |\n");

    printf("|   exit: Quit The Sever                                    |\n");

    printf("|                                                           |\n");

    printf("|   ls : Display All file On the Ftp Server                 |\n");

    printf("|                                                           |\n");

    printf("| get <file>: Download FIle from the Ftp Server             |\n");

    printf("|                                                           |\n");

    printf("| put <file>: Upload FIle to the Ftp Server                 |\n");

    printf("|                                                           |\n");

    printf("=-----------------------------------------------------------=\n");

 

    return ;

}

 

void commd_exit()

{

    printf("Byte!\n");

}

 

void commd_ls(struct sockaddr_in addr, char *commd)

{

    int sockfd;

    //創(chuàng)建套接字

    if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) < 0)

    {

        printf("Socket Error!\n");

        exit(1);

    }

 

    if(connect(sockfd, (SA *)&addr, sizeof(addr)) < 0)

    {

        printf("Connect Error!\n");

        exit(1);

    }

    //將commd指向的內(nèi)容寫(xiě)入到sockfd所指的文件中,此處即指套接字

    if(write(sockfd, commd, N) < 0)

    {

        printf("Write Error!\n");

        exit(1);

    }

 

    while(read(sockfd, commd, N) > 0)  //從sockfd中讀取N字節(jié)內(nèi)容放入commd中,

    {                                   //返回值為讀取的字節(jié)數(shù)

        printf(" %s ",commd);

    }

    printf("\n");

 

    close(sockfd);

    return ;

}

/**************************************************/

/*函數(shù)功能:實(shí)現(xiàn)文件的下載                            */

/**************************************************/

void commd_get(struct sockaddr_in addr, char *commd)

{

    int fd;

    int sockfd;

    char buffer[N];

    int nbytes;

    //創(chuàng)建套接字,并進(jìn)行錯(cuò)誤檢測(cè)

    if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) < 0)

    {

        printf("Socket Error!\n");

        exit(1);

    }

    //connect函數(shù)用于實(shí)現(xiàn)客戶端與服務(wù)端的連接,此處還進(jìn)行了錯(cuò)誤檢測(cè)

    if(connect(sockfd, (SA *)&addr, sizeof(addr)) < 0)

    {

        printf("Connect Error!\n");

        exit(1);

    }

    //通過(guò)write函數(shù)向服務(wù)端發(fā)送數(shù)據(jù)

    if(write(sockfd, commd, N) < 0)

    {

        printf("Write Error!At commd_get 1\n");

        exit(1);

    }

    //利用read函數(shù)來(lái)接受服務(wù)器發(fā)來(lái)的數(shù)據(jù)

    if(read(sockfd, buffer, N) < 0)

    {

        printf("Read Error!At commd_get 1\n");

        exit(1);

    }

    //用于檢測(cè)服務(wù)器端文件是否打開(kāi)成功

    if(buffer[0] =='N')

    {

        close(sockfd);

        printf("Can't Open The File!\n");

        return ;

    }

    //open函數(shù)創(chuàng)建一個(gè)文件,文件地址為(commd+4),該地址從命令行輸入獲取

    if((fd=open(commd+4, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0)

    {

        printf("Open Error!\n");

        exit(1);

    }

    //read函數(shù)從套接字中獲取N字節(jié)數(shù)據(jù)放入buffer中,返回值為讀取的字節(jié)數(shù)

    while((nbytes=read(sockfd, buffer, N)) > 0)

    {

        //write函數(shù)將buffer中的內(nèi)容讀取出來(lái)寫(xiě)入fd所指向的文件,返回值為實(shí)際寫(xiě)入的字節(jié)數(shù)

        if(write(fd, buffer, nbytes) < 0)

        {

            printf("Write Error!At commd_get 2");

        }

    }

 

    close(fd);

    close(sockfd);

 

    return ;

 

}

/**************************************************/

/*函數(shù)功能:實(shí)現(xiàn)文件的上傳                            */

/**************************************************/

void commd_put(struct sockaddr_in addr, char *commd)

{

    int fd;

    int sockfd;

    char buffer[N];

    int nbytes;

    //創(chuàng)建套接字

    if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) < 0)

    {

        printf("Socket Error!\n");

        exit(1);

    }

    //客戶端與服務(wù)端連接

    if(connect(sockfd, (SA *)&addr, sizeof(addr)) < 0)

    {

        printf("Connect Error!\n");

        exit(1);

    }

    //從commd中讀取N字節(jié)數(shù)據(jù),寫(xiě)入套接字中

    if(write(sockfd, commd, N)<0)

    {

        printf("Wrtie Error!At commd_put 1\n");

        exit(1);

    }

    //open函數(shù)從(commd+4)中,讀取文件路徑,以只讀的方式打開(kāi)

    if((fd=open(commd+4, O_RDONLY)) < 0)

    {

        printf("Open Error!\n");

        exit(1);

    }

    //從fd指向的文件中讀取N個(gè)字節(jié)數(shù)據(jù)

    while((nbytes=read(fd, buffer, N)) > 0)

    {

        //從buffer中讀取nbytes字節(jié)數(shù)據(jù),寫(xiě)入套接字中

        if(write(sockfd, buffer, nbytes) < 0)

        {

            printf("Write Error!At commd_put 2");

        }

    }

 

    close(fd);

    close(sockfd);

 

    return ;

}



    下面server.c中后面有些注釋沒(méi)加,感覺(jué)功能上跟client相似,就沒(méi)加,可以參看前面的

//server.c

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <dirent.h>

#include <fcntl.h>

 

#define N 256

 

typedef struct sockaddr SA;

 

void commd_ls(int);

void commd_get(int, char *);

void commd_put(int, char *);

 

int main(int arg, char *argv[])

{

    int ser_sockfd,cli_sockfd;

    struct sockaddr_in ser_addr,cli_addr;

    int ser_len, cli_len;

    char commd [N];

    bzero(commd,N);//將commd所指向的字符串的前N個(gè)字節(jié)置為0,包括'\0'

 

    if((ser_sockfd=socket(AF_INET, SOCK_STREAM, 0) ) < 0)

    {

        printf("Sokcet Error!\n");

        return -1;

    }

 

    bzero(&ser_addr,sizeof(ser_addr));

    ser_addr.sin_family = AF_INET;

    ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);//在TCP連接中,此處類(lèi)似于自動(dòng)獲取ip地址

                                                //在綁定ip時(shí),自動(dòng)選擇ip地址

    ser_addr.sin_port = htons ( 8989 );

    ser_len = sizeof(ser_addr);

    //將ip地址與套接字綁定

    if((bind(ser_sockfd, (SA *)&ser_addr, ser_len)) < 0)

    {

        printf("Bind Error!\n");

        return -1;

    }

    //服務(wù)器端監(jiān)聽(tīng)

    if(listen(ser_sockfd, 5) < 0)

    {

        printf("Linsten Error!\n");

        return -1;

    }

 

    bzero(&cli_addr, sizeof(cli_addr));

    ser_len = sizeof(cli_addr);

 

    while(1)

    {

        printf("server_ftp>");

        //服務(wù)器端接受來(lái)自客戶端的連接,返回一個(gè)套接字,此套接字為新建的一個(gè),并將客戶端的地址等信息存入cli_addr中

        //原來(lái)的套接字仍處于監(jiān)聽(tīng)中

        if((cli_sockfd=accept(ser_sockfd, (SA *)&cli_addr, &cli_len)) < 0)

        {

            printf("Accept Error!\n");

            exit(1);

        }

        //由套接字接收數(shù)據(jù)時(shí),套接字把接收的數(shù)據(jù)放在套接字緩沖區(qū),再由用戶程序把它們復(fù)制到用戶緩沖區(qū),然后由read函數(shù)讀取

        //write函數(shù)同理

        if(read(cli_sockfd, commd, N) < 0)  //read函數(shù)從cli_sockfd中讀取N個(gè)字節(jié)數(shù)據(jù)放入commd中

        {

            printf("Read Error!\n");

            exit(1);

        }

 

        printf("recvd [ %s ]\n",commd);

 

        if(strncmp(commd,"ls",2) == 0)

        {

            commd_ls(cli_sockfd);

        }else if(strncmp(commd,"get", 3) == 0 )

        {

            commd_get(cli_sockfd, commd+4);

        }else if(strncmp(commd, "put", 3) == 0)

        {

            commd_put(cli_sockfd, commd+4);

        }else

        {

            printf("Error!Command Error!\n");

        }

    }

 

    return 0;

}

 

void commd_ls(int sockfd)

{

    DIR * mydir =NULL;

    struct dirent *myitem = NULL;

    char commd[N] ;

    bzero(commd, N);

    //opendir為目錄操作函數(shù),類(lèi)似于open函數(shù)

    //mydir中存有相關(guān)目錄的信息(有待學(xué)習(xí))

    if((mydir=opendir(".")) == NULL)

    {

        printf("OpenDir Error!\n");

        exit(1);

    }

 

    while((myitem = readdir(mydir)) != NULL)

    {

        if(sprintf(commd, myitem->d_name, N) < 0)

        {

            printf("Sprintf Error!\n");

            exit(1);

        }

 

        if(write(sockfd, commd, N) < 0 )

        {

            printf("Write Error!\n");

            exit(1);

        }

    }

 

    closedir(mydir);

    close(sockfd);

 

    return ;

}

 

void commd_get(int sockfd, char *filename)

{

    int fd, nbytes;

    char buffer[N];

    bzero(buffer, N);

 

    printf("get filename : [ %s ]\n",filename);

    if((fd=open(filename, O_RDONLY)) < 0)

    {

        printf("Open file Error!\n");

        buffer[0]='N';

        if(write(sockfd, buffer, N) <0)

        {

            printf("Write Error!At commd_get 1\n");

            exit(1);

        }

        return ;

    }

 

    buffer[0] = 'Y';    //此處標(biāo)示出文件讀取成功

    if(write(sockfd, buffer, N) <0)

    {

        printf("Write Error! At commd_get 2!\n");

        close(fd);

        exit(1);

    }

 

    while((nbytes=read(fd, buffer, N)) > 0)

    {

        if(write(sockfd, buffer, nbytes) < 0)

        {

            printf("Write Error! At commd_get 3!\n");

            close(fd);

            exit(1);

        }

    }

 

    close(fd);

    close(sockfd);

 

    return ;

}

 

void commd_put(int sockfd, char *filename)

{

    int fd, nbytes;

    char buffer[N];

    bzero(buffer, N);

 

    printf("get filename : [ %s ]\n",filename);

    if((fd=open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0)

    {

        printf("Open file Error!\n");

        return ;

    }

 

    while((nbytes=read(sockfd, buffer, N)) > 0)

    {

        if(write(fd, buffer, nbytes) < 0)

        {

            printf("Write Error! At commd_put 1!\n");

            close(fd);

            exit(1);

        }

    }

 

    close(fd);

    close(sockfd);

 

    return ;

}


--------------------- 



標(biāo)簽: 服務(wù)器搭建
分享:
評(píng)論:
你還沒(méi)有登錄,請(qǐng)先