Socket傳輸文件/傳輸圖片(Windows)

利用UDP socket 來傳輸文件與圖片 流程圖如下:
這裏寫圖片描述

主要流程:
1.client端發送command請求,上傳數據或者下載數據,選擇文件路徑;
2.server端應答,start代表開始傳輸,no代表拒絕;
3.fopen打開文件進行讀取(fread)或者寫入(fwrite),爲了支持圖片傳輸,以二進制方式打開文件;

Server端

//udp_server.h
#define BUFLEN 4096
#define SHUTDOWN 0
#define DOWNLOAD 1
#define UPLOAD 2
#define YES 3
#define NO 4
#define START 5
#define END 6
#define CONTENT 7
#define OK 8

struct packet
{
    int command;
    int buflen;  
    int seq;
    char buf[BUFLEN];
};

int socketfd;
int addr_len;
struct sockaddr_in server;
struct sockaddr_in client;
struct packet send_packet;
struct packet recv_packet;
int length;
char ip[20];
int port;
int command;
char file_path[256];
// udp_server.cpp

#include "stdafx.h"

#include <winsock2.h> 
#include "udp_file_server.h"

#pragma comment(lib, "Ws2_32.lib")
#pragma warning(disable:4996)


int main() {
    WSADATA WSAData;
    WSAStartup(MAKEWORD(2, 2), &WSAData);
    /*-------------create UDP socket------------*/
    if ((socketfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("create socket error\n");
        exit(1);
    }

    printf("Server: Please input the ip:\n");
    scanf("%s", ip);
    printf("Please input the port:\n");
    scanf("%d", &port);

    memset(&server,0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(port);
    server.sin_addr.s_addr = inet_addr(ip);
    if (bind(socketfd, (struct sockaddr *)&server, sizeof(server)) == -1) {
        perror("bind error\n");
        exit(1);
    }

    addr_len = sizeof(client);
    while (1) {
        memset(&recv_packet,0, sizeof(recv_packet));
        length = recvfrom(socketfd, (char*)&recv_packet, sizeof(recv_packet), 0, (struct sockaddr *)&client, &addr_len);
        command = recv_packet.command;
        if (command == DOWNLOAD) {
            FILE *fd = fopen((recv_packet.buf), "rb");
            if (fd <0) {
                send_packet.command = NO;
                sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&client, sizeof(client));
                printf(" no such file!\n");
                exit(1);
            }
            else {
                send_packet.command = YES;
                sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&client, sizeof(client));
                recvfrom(socketfd, (char*)&recv_packet, sizeof(recv_packet), 0, (struct sockaddr *)&client, &addr_len);
                if (recv_packet.command == START) {
                    int packet_seq = 0;
                    while ((length = fread(send_packet.buf, 1, BUFLEN,fd)) >0) {
                        send_packet.seq = packet_seq;
                        send_packet.command = CONTENT;
                        send_packet.buflen = length;
                        sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&client, sizeof(client));
                        packet_seq++;
                        memset(&send_packet,0, sizeof(send_packet));
                        Sleep(10);
                    }
                    memset(&send_packet,0, sizeof(send_packet));
                    send_packet.command = END;
                    sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&client, sizeof(client));
                }
            }
        }
        else if (command == UPLOAD) {
            printf("The client want to upload the file:  %s\n", recv_packet.buf);
            printf("Please choice start or no? \n");
            printf("5 :start,  4: no\n");
            scanf("%d", &send_packet.command);
            printf("Please input filepath \n");
            memset(file_path, 0, sizeof(file_path));
            scanf("%s", file_path);

            sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&client, sizeof(client));
            if (send_packet.command == START) {
                int packet_seq = 0;
                FILE *fd = fopen(file_path, "ab");
                if (NULL == fd)
                {
                    printf("fopen return NULL, error=%d/n", GetLastError());
                }
                if (fd < 0) {
                    perror("create file error\n");
                    exit(1);
                }
                memset(&recv_packet,0, sizeof(recv_packet));
                while ((length = recvfrom(socketfd, (char*)&recv_packet, sizeof(recv_packet), 0, (struct sockaddr *)&client, &addr_len)) >0) {
                    if (recv_packet.command == CONTENT) {
                        if ( recv_packet.seq == packet_seq) {
                            fwrite( recv_packet.buf,1,recv_packet.buflen,fd);
                            printf("傳輸數據中...  %s\n", recv_packet.buf);
                            memset(&recv_packet,0, sizeof(recv_packet));
                            packet_seq++;
                        }
                        else {
                            perror("The file no is not same.Some message is missed! error occured! \n");
                            break;
                        }
                    }
                    if (recv_packet.command == END) {
                        fclose(fd);
                        printf("transmission is successful!\n");
                        break;
                    }
                }
            }
            else if (send_packet.command == NO) {
                printf("Not to trans the file\n");
            }
            else {
                perror("error! wrong choice!\n");
                exit(1);
            }

        }
        else if (recv_packet.command == SHUTDOWN) {
            printf("Now the server is shutdown!\n");
            break;
        }
    }
    closesocket(socketfd);
    return 0;
}

Client端

//udp_client.h
#define BUFLEN 4096
#define SHUTDOWN 0
#define DOWNLOAD 1
#define UPLOAD 2
#define YES 3
#define NO 4
#define START 5
#define END 6
#define CONTENT 7
#define OK 8

struct packet
{
    int command;
    int buflen;  
    int seq;
    char buf[BUFLEN];
};

int socketfd;
int addr_len;
struct sockaddr_in server;
struct packet send_packet;
struct packet recv_packet;
int length;
char ip[20];
int port;
int command;
char file_path[256];

void ShowMenu();
void DownLoad();
void UpLoad();
void ShutDown();
// udp_client.cpp

#include "stdafx.h"
#include <winsock2.h> 
#include "udp_file_client.h"

#pragma comment(lib, "Ws2_32.lib")
#pragma warning(disable:4996)


int main() {
    WSADATA WSAData;
    WSAStartup(MAKEWORD(2, 2), &WSAData);
    //創建UDP socket
    if ((socketfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("socket error\n");
        exit(1);
    }

    printf("Client: Please input the ip:\n");
    scanf("%s", ip);
    printf("Please input the port:\n");
    scanf("%d", &port);

    memset(&server,0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(port);
    server.sin_addr.s_addr = inet_addr(ip);
    addr_len = sizeof(server);

    while (1) {
        ShowMenu();
        scanf("%d", &command);
        if (command == SHUTDOWN) {
            ShutDown();
            break;
        }
        else if (command == DOWNLOAD) {
            DownLoad();
        }
        else if (command == UPLOAD) {
            UpLoad();
        }
        else {
            printf("Please make a right choice!\n");
        }
    }
    closesocket(socketfd);
    return 0;
}


void ShowMenu() {
    printf("=====================================\n");
    printf("         Please make a choice:       \n");
    printf("         0:  ||shutdown||            \n");
    printf("         1:  ||download||            \n");
    printf("         2:  || upload ||            \n");
    printf("=====================================\n");
}
void DownLoad() {
    memset(&recv_packet,0, sizeof(recv_packet));
    memset(&send_packet,0, sizeof(send_packet));
    memset(file_path,0, sizeof(file_path));
    printf("Please input the file_path:\n");
    scanf("%s", send_packet.buf);
    send_packet.command = DOWNLOAD;
    sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&server, sizeof(server));
    memcpy(send_packet.buf, file_path, strlen(send_packet.buf));
    recvfrom(socketfd, (char*)&recv_packet, sizeof(recv_packet), 0, (struct sockaddr *)&server, &addr_len);
    if (recv_packet.command == YES) {
        printf("YES!\n");
        int command;
        printf("Press 5 to start  transmission!\n");
        scanf("%d", &command);
        printf("Please input the download path:\n");
        memset(file_path, 0, sizeof(file_path));
        scanf("%s", file_path);
        if (command == START) {
            send_packet.command = START;
            sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&server, sizeof(server));
            int packet_seq = 0;
            FILE *fd = fopen(file_path, "ab");
            if (fd < 0) {
                perror("create file error\n");
                exit(1);
            }
            memset(&recv_packet,0, sizeof(recv_packet));
            while ((length = recvfrom(socketfd, (char*)&recv_packet, sizeof(recv_packet), 0, (struct sockaddr *)&server, &addr_len)) >0) {
                if (recv_packet.command == CONTENT) {
                    if (packet_seq == recv_packet.seq) {
                        fwrite( recv_packet.buf,1, recv_packet.buflen,fd);
                        printf("傳輸數據中... %s\n",recv_packet.buf );
                        memset(&recv_packet,0, sizeof(recv_packet));
                        packet_seq++;
                    }
                    else {
                        perror("The file no is not same.Some message is missed! error occured! \n");
                        break;
                    }
                }
                if (recv_packet.command == END) {
                    fclose(fd);
                    printf("transmission is successful!\n");
                    break;
                }
            }
        }
    }
    else if (recv_packet.command == NO) {
        perror("NO such file on server!\n");
    }
    else {
        perror("recvbuf.command error\n");
        exit(1);
    }
}
void UpLoad() {
    memset(&recv_packet,0, sizeof(recv_packet));
    memset(&send_packet,0, sizeof(send_packet));
    memset(file_path,0, sizeof(file_path));
    printf("Please input the file name:\n");
    scanf("%s", send_packet.buf);
    send_packet.command = UPLOAD;
    sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&server, sizeof(server));
    memcpy( file_path, send_packet.buf, strlen(send_packet.buf));

    FILE *fd = fopen(file_path, "rb");
    if (fd < 0) {
        perror("The file you want to trans is not exist!\n");
        exit(1);
    }
    recvfrom(socketfd, (char*)&recv_packet, sizeof(recv_packet), 0, (struct sockaddr *)&server, &addr_len);
    if (recv_packet.command == START) {
        int packet_seq = 0;
        memset(&send_packet, 0, sizeof(send_packet));
        while ((length = fread(send_packet.buf,1,BUFLEN,fd)) >0) {
            send_packet.seq = packet_seq;
            send_packet.command = CONTENT;
            send_packet.buflen = length;
            sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&server, sizeof(server));
            packet_seq++;
            memset(&send_packet,0, sizeof(send_packet));
            Sleep(10);
        }
        memset(&send_packet,0, sizeof(send_packet));
        send_packet.command = END;
        sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&server, sizeof(server));
    }
    else if (recv_packet.command == NO) {
        printf("not transmission\n");
    }
    else {
        perror("error! wrong choice!\n");
    }
}

void ShutDown() {
    printf("client is shutdown now!\n");
    memset(&send_packet,0, sizeof(send_packet));
    send_packet.command == SHUTDOWN;
    sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&server, sizeof(server));
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章