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);
}
}