Linux TCP 文件传输模块

CLIEN端发给SERVER端.发送数据包的格式是:

1.文件名的大小

2.文件名

3.文件数据大小

4.文件数据

common.h:公共信息

#ifndef COMMON_H
#define COMMON_H

#define SERVER_IP       "192.168.0.88"
#define SERVER_PORT     60021
#define MAX_CONNETCTION 30
#define DEBUG

#endif /*COMMON_H*/

client端

net_send.h:定义了文件传输的相关结构体

#ifndef NET_SEND_H
#define NET_SEND_H

#define MAX_FILE_NAME   255
#define BUF_SIZE        512

#define FD_NOT_SET      0
#define FD_OK           1

#define FAILED          -1
#define SUCCESS         0

typedef struct net_file{
        int file_name_size;
        unsigned long file_data_size;
        int fd;
        int fd_stat;
        char file_to_send[MAX_FILE_NAME];
        char buf[BUF_SIZE];
}netfile_t;

int open_net_file(netfile_t *netfile,char *filename);
int send_net_file(netfile_t *netfile,char *server_ip,short server_port);
void close_net_file(netfile_t *netfile);

#endif /*NET_SEND_H*/

net_send.c:实现文件,关键步骤红色标记

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <libgen.h>
#include "common.h"
#include "net_send.h"

static unsigned long get_file_size(char *filename)
{
        struct stat f_stat;

        if(stat(filename,&f_stat) < 0)
                return 0;

        return (unsigned long)f_stat.st_size;
}

int open_net_file(netfile_t *netfile,char *filename)
{
        if(netfile == NULL || filename == NULL)
                return ;

        bzero(netfile,sizeof(netfile_t));

        memcpy(netfile->file_to_send,basename(filename),strlen(basename(filename)));
#ifdef DEBUG
        printf("netfile->file_to_send = \"%s\".\n",netfile->file_to_send);
#endif
        netfile->fd = open(filename,O_RDONLY);

        if(netfile->fd < 0)
        {
                netfile->fd_stat = FD_NOT_SET;
                return FAILED;
        }

        netfile->file_name_size = strlen(netfile->file_to_send);
        netfile->file_data_size = get_file_size(filename);
#ifdef DEBUG
        printf("filesize = %d.\n",netfile->file_data_size);
#endif
        if(netfile->file_data_size == 0)
        {
                close(netfile->fd);
                netfile->fd_stat = FD_NOT_SET;
                return FAILED;
        }

        netfile->fd_stat = FD_OK;
        return SUCCESS;
}

/*-----sending data-----*/

static int send_block(int sock_fd,const char *buf,int size)
{
        if(send(sock_fd,buf,size,0) < 0)
                return FAILED;
        return SUCCESS;
}

int send_net_file(netfile_t *netfile,char *server_ip,short server_port)
{
        int sock_fd;
        struct sockaddr_in server_addr;
        int bytes_read;

        if(netfile == NULL || server_ip == NULL)
                return FAILED;

        if(netfile->fd_stat == FD_NOT_SET)
                return FAILED;

        if((sock_fd = socket(AF_INET,SOCK_STREAM,0)) == -1)
                return FAILED;

        bzero(&server_addr,sizeof(struct sockaddr_in));

        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(server_port);
        server_addr.sin_addr.s_addr = inet_addr(server_ip);
#ifdef DEBUG
        printf("server ip: %s.\n",inet_ntoa(server_addr.sin_addr));
#endif
        if(connect(sock_fd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == -1)
        {
#ifdef DEBUG
                printf("Cannot connect to server.\n");
#endif
                close(sock_fd);
                return FAILED;
        }

        //First send member "file_name_size" and "file_to_send"
        send(sock_fd,&netfile->file_name_size,sizeof(netfile->file_name_size),0);
        send(sock_fd,netfile->file_to_send,strlen(netfile->file_to_send),0);
        //Then send file_data_size
        send(sock_fd,&netfile->file_data_size,sizeof(netfile->file_data_size),0);
        //Then send file data
        while(1)
        {
               bytes_read = read(netfile->fd,netfile->buf,BUF_SIZE);
                if(bytes_read > 0)
                        send(sock_fd,netfile->buf,bytes_read,0);
                else
                        break;
        }

        close(netfile->fd);
        netfile->fd_stat = FD_NOT_SET;
        close(sock_fd);

        return SUCCESS;
}

/*----close----*/
void close_net_file(netfile_t *netfile)
{
        if(netfile == NULL)
                return ;

        if(netfile->fd_stat == FD_OK)
        {
                netfile->fd_stat = FD_NOT_SET;
                close(netfile->fd);
        }
}

相关推荐