我是靠谱客的博主 激情流沙,最近开发中收集的这篇文章主要介绍搭建tcp的服务器和客户端,实现文件的上传和下载,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

本质:文件的上传和下载本质实际上是对文件的读写操作

上传:将需要上传的文件名发给客户端然后将文件在客户端打开并循环读取至文件末尾,边读边写至和服务器建立的连接管道,服务器接收到文件名后创建一个同名文件,然后打开该文件将客户端写至连接管道的内容读出来并将其写入文件内。这即是文件的上传过程

下载:原理和文件上传类似,只是读写的顺序和目标调换一下

注意:怎样让服务器知道客户端是下载文件还是上传文件,需要客户端发送给服务器一个指令以便让服务器知道客户端想做什么,可以封装一个结构体,成员分别为指令和需要上传或者下载的文件名。

下面直接上代码,代码连在一块的,注释在代码里

服务器端:

头文件

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>

tcp服务器封装


typedef struct fileinfo{
    char filename[64];
    int flag;//判断是下载还是上传指令
}f_info;
    int serverinit()//服务器的封装
{
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd < 0)
    {
        perror("sockfd");
        return -1;
    }

    printf("%dn",sockfd);
    struct sockaddr_in saddr;
    bzero(&saddr,sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = inet_addr("192.168.3.72");
    saddr.sin_port  = htons(8888);
    int ret = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if(ret < 0)
    {
        perror("bind");
        return -1;
    }
    printf("绑定成功  ret =%dn",ret);

    ret = listen(sockfd,5);
    if(ret < 0)
    {
        perror("listen");
        return -1;
    }
    printf("listen.....n");
    return sockfd;
}
int main(int argc, char *argv[])
{ 
    int sockfd =  serverinit();
    struct sockaddr_in caddr;
    socklen_t len = sizeof(caddr);

    int connfd = accept(sockfd,(struct sockaddr*)&caddr,&len);//接受客户端的连接
    if(connfd < 0 )
    {
        perror("accept");
        return -1;
    }
    printf("connect success  ip:%s ----- port:%u n",inet_ntoa(caddr.sin_addr),ntohs(caddr.sin_port));
    f_info info;
    //char filename[64] = {0};
    int ret = read(connfd,&info,sizeof(info));//接收带有文件上传或下载的结构体信息
    if(ret < 0)
    {
        perror("read");
        return -1;
    }

    switch(info.flag)//判断指令是上传或下载
    {
        case 1://上传
            {
        int rfd = open(strcat(info.filename,"1"),O_RDWR | O_CREAT | O_TRUNC,0664);
        bzero(info.filename,sizeof(info.filename));
        while((ret = read(connfd,info.filename,sizeof(info.filename))) > 0)//读取客户端发送过来的文件内容
        {
            printf("%dn",ret);
            write(rfd,info.filename,ret);//写到创建好的文件里
        }
        break;
            }
        case 2:下载
            {
                int wfd = open(info.filename,O_RDONLY);
                bzero(info.filename,sizeof(info.filename));
                if(wfd < 0)
                {
                    perror("open");
                    return -1;
                }
                while( (ret = read(wfd,info.filename,sizeof(info.filename))) > 0)//从服务器本地的文件读取内容
                {
                    write(connfd,info.filename,ret);//写至和客户端建立好的连接管道
                }
                break;
            }
            
    }
    close(connfd);
    close(sockfd);
    return 0;
} 

客户端:

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>

tcp客户端的封装

typedef struct fileinfo{
    char filename[64];
    int flag;//判断是下载还是上传
}f_info;
int clientcon(char *addr,unsigned short port)
{
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd < 0)
    {
        perror("sockfd");
        return -1;
    }

    printf("%dn",sockfd);
    struct sockaddr_in saddr;
    bzero(&saddr,sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = inet_addr(addr);
    saddr.sin_port  = htons(port);
    int ret = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if(ret < 0)
    {
        perror("connect");
        return -1;
    }
    printf("connect successn");
    return sockfd;
}



int main(int argc, char *argv[])
{ 
   int sockfd =  clientcon("192.168.3.72",8888);
   f_info info;
   printf("%dn",sockfd);
   //int op;
   int ret;
   strcpy(info.filename,"0");
   info.flag = 0;
   char buf[64] = {0};
   int fd = 0;
    printf("---------欢迎来到文件传输系统--------n");
    printf("1.上传文件------2.下载文件------n");
    
    scanf("%d",&info.flag);
    switch(info.flag)
    {
        case 1://客户端上传
            {
                getchar();
                printf("请输入要上传的文件名:n");
                fgets(info.filename,64,stdin);
                info.filename[strlen(info.filename) - 1] = '';
            //    write(sockfd,filename,sizeof(filename));

                write(sockfd,&info,sizeof(info));//将带有指令的信息发送至服务器

                //以下即是对文件的读写操作,包括与服务器建立好的连接管道读写(sockfd)和上传下载文件读写(fd)
                 fd = open(info.filename,O_RDONLY);

                if(fd < 0)
                {
                    perror("open");
                    return -1;
                }
                
                while((ret = read(fd,buf,sizeof(buf))) > 0)
                {
                    printf("%dn",ret);
                    write(sockfd,buf,ret);
                }
                printf("文件上传成功n");
               // printf("ret=%dn",ret);
                break;
            }
        case 2://客户端下载
            {
                getchar();
                printf("请输入要下载的文件名:n");
                fgets(info.filename,sizeof(info.filename),stdin);
                info.filename[strlen(info.filename) - 1] = '';
                write(sockfd,&info,sizeof(info));
                int fd = open(strcat(info.filename,"11"),O_CREAT | O_WRONLY | O_TRUNC,0664);
                 if(fd < 0)
                 {
                     perror("open");
                     return -1;
                 }
                while((ret = read(sockfd,buf,sizeof(buf))) > 0)
                {
                    write(fd,buf,ret);
                }
                printf("文件下载成功n");
                //printf("rret = %dn",ret);
                break;
            }
    }

  

    
    close(sockfd);
    return 0;
}

以上便我是对文件下载和上传所分享的内容,如有不妥还请指正

最后

以上就是激情流沙为你收集整理的搭建tcp的服务器和客户端,实现文件的上传和下载的全部内容,希望文章能够帮你解决搭建tcp的服务器和客户端,实现文件的上传和下载所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部