传文件通用(结构体)

通过结构体传文件

服务器代码:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

#include <sys/stat.h>

#define N 512
//每次上传一个结构体
typedef struct file
{
    int len_max;//文件最大长度
    int len;//本次传输的长度
    char buf[N];//传输的内容
}File;

//传输显示
void bar(int x,int max)
{
    system("clear");
    int i,k;
    k = x*1.0/max*100;
    printf("/");
    for(i = 0; i < k/5; i++)
    {
        printf("#");
    }
    for(i = 0; i < 20-k/5; i++)
    {
        printf("*");
    }
    printf("/%d%%\n",k);
    //延时只是为了显示效果没啥用可以自己调
    usleep(50000);
}
//套接字初始化
//三个参数分别为IP、端口号、允许最大连接
int tcp_server_init(char *ip, int port, int backlog)
{
    //创建套接字文件打通软件和硬件的关节
    int skt = socket(AF_INET, SOCK_STREAM, 0);
    if(-1 == skt)
    {
        printf("socker error\n");
        return -1;
    }
    //将IP和端口号存入结构体
    struct sockaddr_in sddr;
    sddr.sin_family     = AF_INET;
    sddr.sin_port       = htons(port);
    sddr.sin_addr.s_addr    = inet_addr(ip);
    //将套接字和IP、端口号进行绑定
    int ret = bind(skt, (struct sockaddr *)&sddr, sizeof(sddr));
    if(-1 == ret)
    {
        printf("bind error\n");
        return -1;
    }
    //监听套接字并设置最大链接数量
    ret = listen(skt, backlog);
    if(-1 == ret)
    {
        printf("listen error\n");
        return -1;
    }
    puts("listen....");
    return skt;
}
//连接函数
//参数是打开的套接字文件描述符
int tcp_wait_connect(int skt)
{
    struct sockaddr_in cddr;
    int len = sizeof(cddr);            
    int nfd = accept(skt, (void *)&cddr, &len);
    if(-1 == nfd)
    {
        perror("accept error\n");
        return -1;
    }
    return nfd;
}

int main(int argc, char *argv[])
{    
    char tmp[3] = {'\0'};
    int skt = tcp_server_init("0.0.0.0", 6666, 10);
    int nfd = tcp_wait_connect(skt);
    File file = {'\0'};
    read(nfd, tmp, sizeof(tmp));
    int fr = open(argv[1], O_RDONLY);
    if(-1 == fr)
    {
        printf("open error\n");
        return -1;
    }
        
    //计算文件大小
    struct stat str;
    stat(argv[1], &str);
    file.len_max = str.st_size;
        
    int count = 0;
    if(0 == strcmp(tmp,"go"))
    {
         while(1)
         {
             file.len = read(fr, file.buf, sizeof(file.buf));
             count = file.len + count;
             bar(count, file.len_max);
             write(nfd, &file, sizeof(file));
             if(0 == file.len)
             {
                 break;
             }
         }
    }
    printf("上传完成!\n");
    close(fr);
    close(skt);
    close(nfd);
    return 0;
}

 

客户端代码:

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

//一次接收的字节数建议不要超过512且需要与服务器一次上传的字节数一至
#define N 512
//每次接收一个结构体
typedef struct file
{
    int len_max;//文件最大长度
    int len;//本次传输的长度
    char buf[N];//传输的内容
}File;

//传输显示
void bar(int x,int max)
{
    system("clear");
    int i,k;
    k = x*1.0/max*100;
    printf("/");
    for(i = 0; i < k/5; i++)
    {
        printf("#");
    }
    for(i = 0; i < 20-k/5; i++)
    {
        printf("*");
    }
    printf("/%d%%\n",k);
    //延时只是为了显示效果没啥用可以自己调
    usleep(50000);
}


int main(int argc, char *argv[])
{
    //创建套接字
    int skt = socket(AF_INET, SOCK_STREAM, 0);
    if(-1 == skt)
    {
        printf("socket error\n");
        return -1;
    }
    //将IP、端口号存入结构体
    struct sockaddr_in sddr;
    sddr.sin_family     = AF_INET;
    sddr.sin_port       = htons(atoi(argv[2]));
    sddr.sin_addr.s_addr    = inet_addr(argv[1]);
    //绑定
    int ret = connect(skt, (struct sockaddr *)&sddr, sizeof(sddr));
    if(-1 == ret)
    {
        printf("connect error\n");
        return -1;
    }
    //标识符
    char tmp[3] = {'\0'};
    File file = {'\0'};
    //创建或打开一个文件存放下载的内容
    int fr = open(argv[3], O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if(-1 == fr)
    {
        printf("open error\n");
        return -1;
    }
    printf("要开始吗?");
    int count = 0;
    //输入指定字符开始下载
    fgets(tmp,sizeof(tmp),stdin);
    write(skt, tmp, 2);
    while(1)
    {
        read(skt, &file, sizeof(file));
        if(0 == file.len)
        {
            break;
        }
        count = file.len + count;
            bar(count, file.len_max);
        write(fr, file.buf, file.len);
    }
    printf("下载完成!\n");
    close(skt);
    close(fr);
    return 0;
}

Makefile

APP:
    gcc -g server.c -o server
    gcc -g app.c -o app
R1:
    ./server qy.jpg
R2:
    ./app 192.168.10.159 6666 wf.jpg

 

posted @ 2022-04-04 14:16  西北小蚂蚁  阅读(32)  评论(0编辑  收藏  举报