Socket网络编程: 应用

ftp服务器

客户端

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<unistd.h>
#include<time.h>
#define BUFLEN 1024
char *SERVERIP="127.0.0.1";
int SERVER_PORT=23336;
int my_BUFSIZ=4096;
int FILE_NAME_MAX_SIZE=512;
void binner()
{
    printf("               【多进程版·ftpclient:Linux】              \n");
    printf("    _  _  _  _           _           _        _           _ \n");
    printf("   (_)(_)(_)(_) _       (_)_       _(_)      (_)_       _(_)\n");
    printf("   (_)         (_)        (_)_   _(_)          (_)_   _(_)  \n");
    printf("   (_) _  _  _ (_)          (_)_(_)              (_)_(_)    \n");
    printf("   (_)(_)(_)(_)              _(_)_                 (_)      \n");
    printf("   (_)   (_) _             _(_) (_)_               (_)      \n");
    printf("   (_)      (_) _        _(_)     (_)_             (_)      \n");
    printf("   (_)         (_)      (_)         (_)            (_)      \n");
    printf("                                                            \n");
}
void menue()
{
    printf("\n使用说明:\n");
    printf("-h:帮助 \n");
    printf("-l:服务器地址,默认127.0.0.1\n");
    printf("-p:端口,默认23334 \n");
    printf("-b:发送数据大小,默认4096\n");
    printf("-f:文件最大,默认512\n");
}
int main(int argc,char **argv)
{
    binner();
    menue();
    if(argc>1)
    {
        if(strcmp(argv[1],"-h")==0)
        {

            exit(-1);
        }
        else
        {
            for(int i=1;i<argc;++i)
            {
                if(strcmp(argv[i],"-p")==0)
                {
                    SERVER_PORT=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-b")==0)
                {
                    my_BUFSIZ=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-l")==0)
                {
                    SERVERIP = argv[i+1];
                }
                else if(strcmp(argv[i],"-f")==0)
                {
                    FILE_NAME_MAX_SIZE=atoi(argv[i+1]);
                }
            }

        }
    }
    printf("【TCP客户端:目标IP %s,监听端口 %d,发送数据大小:%d,发送文件名最大:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE);

    int tsock;
    tsock=socket(AF_INET,SOCK_STREAM,0);
    if(tsock<0)
    {
        printf("Create Socket Failed! \n");
        exit(-1);
    }
    struct sockaddr_in servaddr;
    memset(&servaddr,0,sizeof(servaddr));
    servaddr.sin_family=AF_INET;
    inet_aton(SERVERIP,&servaddr.sin_addr);
    servaddr.sin_port=htons(SERVER_PORT);

    int ret;
    ret=connect(tsock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr));
    if(ret<0)
    {
        printf("Connect Failed!\n");
        exit(-1);
    }
  
    
    char buf[BUFLEN];
    memset(buf,'\0',sizeof(buf));
    //接受服务器的文件名
    if(recv(tsock,buf,sizeof(buf),0)>0)
    {
        printf("ftpclient>>\n");
        printf("***************ftp_server当前目录文件***************\n");
        puts(buf);//将结果显示在屏幕上
        printf("*****************1.上传文件 2.下载文件*************\n");
    }
    else
    {
        puts("ftpclient>>\n接受文件失败!\n");
        exit(-1);
    }
    memset(buf, '\0',sizeof(buf));
    printf("ftpclient>>");
    scanf("%s",buf);
    //向服务器发送选择
    if(send(tsock,buf,strlen(buf),0)<0)
    {
        puts("ftpclient>>发送数据失败!");
        exit(-1);
    }
    if(strcmp(buf,"1")==0)
    {
        //上传文件        
        char file_name[FILE_NAME_MAX_SIZE+1];
        memset(file_name,'\0',sizeof(file_name));
        printf("ftpclient>>");
        scanf("%s",file_name);
        int len_file=strlen(file_name);
        file_name[len_file+1]='\0';
       if(send(tsock,file_name,len_file+1,0)<0)
        {
            puts("ftpclient>>发送文件名失败!");
            exit(-1);
        }
        FILE * fp=fopen(file_name,"r");
        printf("%s\n",file_name);
        if(fp==NULL)
        {
            printf("ftpclient>>文件%s不存在\n",file_name);
        }
        else
        {
            char buffer[my_BUFSIZ];
            memset(buffer,'\0',my_BUFSIZ);
            int file_block_length=0;
            while((file_block_length=fread(buffer,sizeof(char),my_BUFSIZ,fp))>0)
            {
               // printf("ftpserver>>文件块大小:%d\n",file_block_length);
                if(send(tsock,buffer,file_block_length,0)<0)
                {
                   printf("ftpclient>>文件%s发送失败\n",file_name);
                    break;
                    exit(-1);                               
                }
                memset(buffer,'\0',my_BUFSIZ);
            }
            fclose(fp);
            printf("ftpclient>>文件%s发送成功\n",file_name);
        }
    }
    else if(strcmp(buf,"2")==0)
    {
        //下载文件
        char file_name[FILE_NAME_MAX_SIZE+1];
        memset(file_name,'\0',sizeof(file_name));
        printf("ftpclient>>");
        scanf("%s",file_name);
        
            //向服务器发送buffer中的数据,buffer中放的是文件的名字
        if(send(tsock,file_name,strlen(file_name),0)<0)
        {
            printf("ftpclient>>发送数据失败!\n");
            exit(-1);
        }
        
        //接受文件
        FILE *fp = fopen(file_name,"w");
        if(fp==NULL)
        {
            printf("ftpclient>>文件%s不可打开\n",file_name);
            exit(-1);
        }
        char buffer[my_BUFSIZ];
        memset(buffer,'\0',my_BUFSIZ);
        int num;
        while(num=recv(tsock,buffer,my_BUFSIZ,0))
        {
          //  printf("ftpclient>>接收文件长度:%d\n",num);
            if(num < 0)
            {
                printf("ftpclient>>接收数据失败!\n");
                break;
            }
            int write_len = fwrite(buffer,sizeof(char),num,fp);
            
            if(write_len!=num)
            {
                printf("ftpclient>>文件%s写入失败\n",file_name);
                break;
            }
            memset(buffer,'\0',my_BUFSIZ);
        }
       // printf("ftpclient>>接收文件长度:%d\n",num);
        printf("ftpclient>>接收文件%s成功\n",file_name);
        fclose(fp);
    }
    
    //从服务器获取文件
    
    close(tsock);

    return 0;
}

 

服务器

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<unistd.h>
#include<time.h>
#include<signal.h>
#include<stdlib.h> 
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BUFLEN 1024
int SERVER_PORT = 23336 ;
int my_BUFSIZ=1024;
int FILE_NAME_MAX_SIZE=512;
int LISTEN=30;
int COMMOND_LEN=1024; 
int PIDNUM=3;
void binner()
{
    printf("               【多进程版·ftpserver:Linux】                \n");
    printf("    _  _  _  _           _           _        _           _ \n");
    printf("   (_)(_)(_)(_) _       (_)_       _(_)      (_)_       _(_)\n");
    printf("   (_)         (_)        (_)_   _(_)          (_)_   _(_)  \n");
    printf("   (_) _  _  _ (_)          (_)_(_)              (_)_(_)    \n");
    printf("   (_)(_)(_)(_)              _(_)_                 (_)      \n");
    printf("   (_)   (_) _             _(_) (_)_               (_)      \n");
    printf("   (_)      (_) _        _(_)     (_)_             (_)      \n");
    printf("   (_)         (_)      (_)         (_)            (_)      \n");
    printf("                                                            \n");
    /*
    服务器发送文件
    */
}
void menue()
{
    printf("\n使用说明:\n");
    printf("-h:帮助 \n");
    printf("-p:端口,默认23334 \n");
    printf("-b:发送数据大小,默认4096\n");
    printf("-f:文件最大,默认512\n");
    printf("-s:最大连接量,默认3\n");
}


#define maxn 10000000
int prime[maxn],x;
_Bool vis[maxn];
void oulasai(int n)  //欧拉筛
{
    memset(prime,0,sizeof(prime));
    memset(vis,0,sizeof(vis));
    for(int i=2;i<=n;i++)
    {
        if(!vis[i]) prime[x++]=i;
        for(int j=0;j<x;j++)
        {
            if(i*prime[j]>n) break;
            vis[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
}
void send_prime_in_range(char *buf,int ssock)
{
    //求出质数
    memset(buf,'\0',sizeof(buf));
    printf("ftpserver>>客户端要求的范围0-%s:\n",buf);
    int num = atoi(buf);
    x=0;
    int index=0;
    char res[my_BUFSIZ];
    oulasai(num);
    memset(buf,'\0',sizeof(buf));
    for(int i=0;i<x;i++)
    {
        sprintf(res,"%d",prime[i]);
        for(int j=0;j<strlen(res);++j)
        {
            buf[index++]=res[j];
        }
        buf[index++]=',';
    }
        
    printf("ftpserver>>发送的字符串:%s\n",buf);
    send(ssock,buf,strlen(buf),0);
}
void commend_exec(int ssock,char *cmd)
{
    DIR *dp=opendir(".");
    struct dirent *entry;
    char commd[COMMOND_LEN];
    memset(commd,'\0',sizeof(commd));
    while((entry = readdir(dp))!=NULL)
    {
        strcat(commd,entry->d_name);
        strcat(commd,"    ");
    }
    send(ssock,commd,strlen(commd),0);
}
static void handle_fork (int msock)
{
    if(listen(msock,LISTEN)<0)
    {
        printf("ftpserver>>监听失败!\n");
        exit(-1);
    }
    
    char buf [BUFLEN] ;
    time_t now;
    
    int ssock;
    struct sockaddr_in clientaddr;
    socklen_t len=sizeof(struct sockaddr_in);
    memset(&clientaddr,0,len);
    ssock=accept(msock,(struct sockaddr*)&clientaddr,&len);
    if(ssock<0)
    {
        printf("ftpserver>>Accept Failed!");
        exit(-1);
    }
    
    printf("\n*****************通信开始****************\n");
    printf("ftpserver>>正在通信的客户端是:%s: %d\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));

    //ftp_server(ssock);
    commend_exec(ssock,".");
    char commd[COMMOND_LEN];
    memset(commd,'\0',sizeof(commd));
    if(recv(ssock,commd,sizeof(commd),0)<0)
    {
        printf("ftpserver>>接受客户端选择失败!\n");
        exit(-1);
    }
    printf("ftpserver>>客户端的选择:%s\n",commd);
    if(strcmp(commd,"1")==0)
    {
         //下载文件
        char file_name[FILE_NAME_MAX_SIZE+1];
        memset(file_name,'\0',strlen(file_name));
        
        if(recv(ssock,file_name,FILE_NAME_MAX_SIZE,0)<0)
        {
            printf("ftpserver>>接受文件名失败!\n");
            exit(-1);
        }
        
        //接受文件体
        FILE *fp = fopen(file_name,"w");
        //printf("%s",file_name)
        if(fp==NULL)
        {
            printf("ftpserver>>文件\"%s\"不可打开\n",file_name);
            exit(-1);
        }
        char buffer[my_BUFSIZ];
        memset(buffer,'\0',my_BUFSIZ);
        int num;
        while(num=recv(ssock,buffer,my_BUFSIZ,0))
        {
          //  printf("ftpclient>>接收文件长度:%d\n",num);
            if(num < 0)
            {
                printf("ftpserver>>接收数据失败!\n");
                break;
            }
            int write_len = fwrite(buffer,sizeof(char),num,fp);
            
            if(write_len!=num)
            {
                printf("ftpserver>>文件%s写入失败\n",file_name);
                break;
            }
            memset(buffer,'\0',my_BUFSIZ);
        }
       // printf("ftpclient>>接收文件长度:%d\n",num);
        printf("ftpclient>>接收文件%s成功\n",file_name);
        fclose(fp);
    
    }
    else if(strcmp(commd,"2")==0)
    {
        //接受文件
       
        char buffer[my_BUFSIZ];
        memset(buffer,'\0',sizeof(buffer));
        if(recv(ssock, buffer, sizeof(buffer), 0)<0)
        {
            printf("ftpserver>>接收文件名失败\n");
            exit(-1);
        }
        else
        {
            printf("ftpserver>>请求文件名%s\n",buffer);
        }
        char file_name[FILE_NAME_MAX_SIZE+1];
        memset(file_name,'\0',sizeof(file_name));
        //将文件名从缓冲区buffer拷贝到文件名数组里面
       strncpy(file_name,buffer,strlen(buffer)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE:strlen(buffer));
        FILE * fp=fopen(file_name,"r");
        if(fp==NULL)
        {
            printf("ftpserver>>文件%s不存在\n",file_name);
        }
        else
        {
            memset(buffer,'\0',my_BUFSIZ);
            int file_block_length=0;
            while((file_block_length=fread(buffer,sizeof(char),my_BUFSIZ,fp))>0)
            {
                //printf("ftpserver>>文件块大小:%d\n",file_block_length);
                if(send(ssock,buffer,file_block_length,0)<0)
                {
                    printf("ftpserver>>文件:%s 发送失败\n",file_name);
                    break;
                }
                memset(buffer,'\0',my_BUFSIZ);
            }
            fclose(fp);
            printf("ftpserver>>文件%s发送成功\n",file_name);
        }
    }
    
    
    close(ssock);
    close(msock);
    return;
}
int main(int argc,char**argv)
{
    binner();
    menue();
    if(argc>1)
    {
        if(strcmp(argv[1],"-h")==0)
        {
            binner();
            menue();
            exit(-1);
        }
        else
        {
            for(int i=1;i<argc;++i)
            {
                if(strcmp(argv[i],"-p")==0)
                {
                    SERVER_PORT=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-b")==0)
                {
                    my_BUFSIZ=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-f")==0)
                {
                    FILE_NAME_MAX_SIZE=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-s")==0)
                {
                    PIDNUM=atoi(argv[i+1]);
                }
            }

        }
    }


    printf("【TCP服务端:监听端口 %d,发送数据大小:%d,发送文件最大:%d,最大连接数:%d】\n\n",SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE,PIDNUM);

    int msock;
    pid_t pid[PIDNUM];
    msock=socket(AF_INET,SOCK_STREAM,0);
    if(msock<0)
    {
        printf("Create Socket Failed!\n");
        exit(-1);
    }

    struct sockaddr_in servaddr;
    memset(&servaddr,0,sizeof(servaddr));
    servaddr.sin_family=AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(SERVER_PORT);

    int ret;
    ret=bind(msock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr_in));
    if(ret<0)
    {
        printf("Server Bind Port: %d Failed!\n",SERVER_PORT);
        exit(-1);
    }

    ret=listen(msock,LISTEN);
    if(ret<0)
    {
        printf("Listen Failed!\n");
        exit(-1);
    }

    signal(SIGCLD,SIG_IGN);
    int i=0;
    for (i=0;i<PIDNUM;i++)
    {
        pid[i]=fork();
        if(pid[i]==0)
            handle_fork(msock);
    }
    close(msock);
    return 0;
}

 

运行效果

 

posted @ 2020-11-25 00:24  东坡肉肉君  阅读(75)  评论(0编辑  收藏  举报