Chinaunix首页 | 论坛 | 博客
  • 博客访问: 36095
  • 博文数量: 8
  • 博客积分: 1482
  • 博客等级: 上尉
  • 技术积分: 90
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-18 13:55
文章分类

全部博文(8)

文章存档

2011年(1)

2008年(7)

我的朋友

分类: C/C++

2008-10-28 19:59:45

   写了一个UDP文件传送程序,但是有一些东西传送之后大小发生了变化,不知道什么原因,也不知道这样写对不对,希望哪位路过的大虾指点一二,但是传一般的字符文件没问题。代码:

/*
 * filename: client.c
 * DESC: the client endpoint of the UDP sending files program
 * Author: linjian < lin.jian1986@gmail.com >
 * Date: 2008/10/28
 */


#include <unistd.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT         8003
#define BUF_SIZE    512

#define err_quit( MESSAGE ) \
         perror( MESSAGE ),    \
        exit ( EXIT_FAILURE )

/*
 * @name: the filename
 * @sockfd: the file desc
 * @addr: the server's address
 * DESC: the client endpoints send the filename to the server endpoint
 */

void client_send_filename( const char *name, int sockfd, struct sockaddr_in addr )
{
    int addr_len = sizeof(addr );
    if ( sendto(sockfd, name, strlen(name), 0, (struct sockaddr *)&addr, addr_len) < 0 )
        err_quit( "sendto failed" );
}

/*
 * @name: the filename
 * @sockfd: the file desc
 * @addr: the server's address
 * DESC: the client endpoints send the file to the server endpoint
 */

void client_send_file( const char *name, int sockfd, struct sockaddr_in addr )
{
    int fd;
    int addr_len;
    int num_bytes;
    char buffer[ BUF_SIZE ];

    if ( (fd = open(name, O_RDONLY)) < 0 )
        err_quit( "open failed" );

    addr_len = sizeof( addr );
    do {
        num_bytes = read(fd, buffer, BUF_SIZE);
        sendto( sockfd, buffer, num_bytes, 0, (struct sockaddr *)&addr, addr_len );
    } while ( num_bytes > 0 );

    fputs( "Done\n", stdout );
    close( fd );
}

/*
 * @result: get the filename
 * @name; the file which will be send
 * DESC: get the filename
 */

void get_filename( char result[], char name[] )
{
    char *ptr = name;
    char *temp = ptr;
    char *substr = "/";
    
    ptr = strstr(name, substr);
    if ( ptr != NULL )
        temp = ptr;

    while ( ptr ) {
        ptr = strstr( ptr + 1, substr );
        if ( ptr != NULL )
            temp = ptr;
    }

    strcpy( result, temp + 1);
}

int main( int argc, char *argv[] )
{
    int sockfd;
    char filename[ BUF_SIZE ] = { 0 };
    struct sockaddr_in addr;


    if ( argc != 3 ) {
        printf( "usage: ./client [ip] [file]\n" );
        exit ( EXIT_FAILURE );
    }

    if ( (sockfd = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 )
        err_quit( "socket failed" );

    addr.sin_family = AF_INET;
    addr.sin_port = htons( PORT );
    addr.sin_addr.s_addr = inet_addr( argv[1] );
    bzero( &(addr.sin_zero), 8 );

    get_filename( filename, argv[2] );
    client_send_filename( filename, sockfd, addr );
    
    client_send_file( argv[2], sockfd, addr );

    close( sockfd );
    return 0;
}

/*
 * filename: sever.c
 * DESC: the server endpoint of the UDP sending files program
 * Author: linjian < lin.jian1986@gmail.com >
 * Date: 2008/10/28
 */


#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define PORT         8003
#define FILE_MODE 0777
#define BUF_SIZE    512

#define err_quit( MESSAGE ) \
         perror( MESSAGE ),    \
        exit ( EXIT_FAILURE )

/*
 * @name: the file's name
 * @sockfd: the file desc
 * DESC: the server endpoint get the filename
 */

void server_recv_filename( char name[], int sockfd )
{
    struct sockaddr_in addr;
    int addr_len = sizeof( struct sockaddr );

    if ( recvfrom(sockfd, name, BUF_SIZE, 0, (struct sockaddr *)&addr, &addr_len) < 0 )
        err_quit( "recvfrom failed" );
}

/*
 * @name: the file's name
 * @sockfd: the file desc
 * @addr: the client endpoint's address
 * DESC: the server endpoint recieve the file
 */

void server_recv_file( const char *name, int sockfd, struct sockaddr_in addr )
{
    int fd;
    int num_bytes = 0;
    int addr_len = sizeof( struct sockaddr );
    char buffer[ BUF_SIZE ] = { 0 };

    /* create the file with the filename */
    if ( (fd = open( name, O_WRONLY | O_CREAT | O_TRUNC, FILE_MODE )) < 0 )
        err_quit( "open failed" );

    do {
        num_bytes = recvfrom( sockfd, buffer, BUF_SIZE, 0, (struct sockaddr *)&addr,
                      &addr_len);
        write( fd, buffer, num_bytes );
    } while ( num_bytes > 0 );

    close( fd );
}

int main( int argc, char *argv[] )
{
    int sockfd;
    int bindfd;
    char filename[ BUF_SIZE ] = { 0 };

    struct sockaddr_in addr;

    if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 )
        err_quit( "socket failed" );

    addr.sin_family = AF_INET;
    addr.sin_port = htons( PORT );
    addr.sin_addr.s_addr = htons( INADDR_ANY );
    bzero( &(addr.sin_zero), 8 );

    if ( bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0 )
        err_quit( "bind failed" );
    
    server_recv_filename( filename, sockfd );
    server_recv_file( filename, sockfd, addr );

    close( sockfd );
    return 0;
}

ken@ken-laptop:~/linux_c/others/tcp_send_files$ ls

client client.c sever sever.c

ken@ken-laptop:~/linux_c/others/tcp_send_files$ ./client 127.0.0.1 ../../test.c

Done

ken@ken-laptop:~/linux_c/others/tcp_send_files$ ls

client client.c sever sever.c test.c

// 对比上面,多出了一个test.c,这个就是传送的文件了

阅读(1858) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~