1. 程式人生 > 其它 >傳檔案通用(結構體)

傳檔案通用(結構體)

通過結構體傳檔案

伺服器程式碼:

#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