基于UDP的TFTP文件上传
# include <myhead.h> # define PORT 69
# define IP "192.168.125.59" int down ( const char * ) ;
int up ( const char * ) ; int main ( int argc, const char * argv[ ] )
{ while ( 1 ) { system ( "clear" ) ; puts ( "***************功能**************" ) ; puts ( "*************1. 下载*************" ) ; puts ( "*************2. 上传*************" ) ; puts ( "*************3. 退出*************" ) ; int choose = - 1 ; char filename[ 128 ] = "" ; scanf ( "%d" , & choose) ; switch ( choose) { case 1 : { printf ( "输入文件名>>" ) ; scanf ( " %[^\n]" , filename) ; if ( down ( filename) == - 1 ) { return - 1 ; } } break ; case 2 : { printf ( "输入文件名>>" ) ; scanf ( " %[^\n]" , filename) ; if ( up ( filename) == - 1 ) { return - 1 ; } } break ; case 3 : return 0 ; default : puts ( "输入错误" ) ; } } return 0 ;
} int down ( const char * filename) { int cfd = socket ( AF_INET, SOCK_DGRAM, 0 ) ; if ( cfd == - 1 ) { perror ( "socket error" ) ; return - 1 ; } char buf[ 516 ] ; bzero ( buf, sizeof ( buf) ) ; buf[ 1 ] = 1 ; strcpy ( buf+ 2 , filename) ; char mod[ 6 ] = "octet" ; strcpy ( buf+ 2 + strlen ( filename) + 1 , mod) ; int size = 2 + strlen ( filename) + 1 + strlen ( mod) + 1 ; struct sockaddr_in sin; sin. sin_family = AF_INET; sin. sin_port = htons ( PORT) ; sin. sin_addr. s_addr = inet_addr ( IP) ; socklen_t socklen = sizeof ( sin) ; if ( sendto ( cfd, buf, size, 0 , ( struct sockaddr * ) & sin, sizeof ( sin) ) == - 1 ) { perror ( "sendto error" ) ; return - 1 ; } puts ( "请求成功" ) ; int fd = open ( filename, O_WRONLY | O_CREAT | O_TRUNC, 0664 ) ; while ( 1 ) { bzero ( buf, sizeof ( buf) ) ; int res = - 1 ; if ( ( res = recvfrom ( cfd, buf, sizeof ( buf) , 0 , ( struct sockaddr * ) & sin, & socklen) ) == - 1 ) { perror ( "recvfrom error" ) ; return - 1 ; } if ( buf[ 1 ] == 3 ) { if ( res < 516 ) { write ( fd, buf+ 4 , res- 4 ) ; buf[ 1 ] = 4 ; sendto ( cfd, buf, 4 , 0 , ( struct sockaddr * ) & sin, sizeof ( sin) ) ; break ; } else { write ( fd, buf+ 4 , 512 ) ; buf[ 1 ] = 4 ; sendto ( cfd, buf, 4 , 0 , ( struct sockaddr * ) & sin, sizeof ( sin) ) ; } } else { printf ( "未知错误,错误码: %d\n" , buf[ 3 ] ) ; close ( fd) ; close ( cfd) ; return - 1 ; } } close ( fd) ; close ( cfd) ; return 0 ;
} int up ( const char * filename) { int cfd = socket ( AF_INET, SOCK_DGRAM, 0 ) ; if ( cfd == - 1 ) { perror ( "socket error" ) ; return - 1 ; } char buf[ 516 ] ; bzero ( buf, sizeof ( buf) ) ; buf[ 1 ] = 2 ; strcpy ( buf+ 2 , filename) ; char mod[ 6 ] = "octet" ; strcpy ( buf+ 2 + strlen ( filename) + 1 , mod) ; int size = 2 + strlen ( filename) + 1 + strlen ( mod) + 1 ; struct sockaddr_in sin; sin. sin_family = AF_INET; sin. sin_port = htons ( PORT) ; sin. sin_addr. s_addr = inet_addr ( IP) ; socklen_t socklen = sizeof ( sin) ; if ( sendto ( cfd, buf, size, 0 , ( struct sockaddr * ) & sin, sizeof ( sin) ) == - 1 ) { perror ( "sendto error" ) ; return - 1 ; } puts ( "请求成功" ) ; int fd = open ( filename, O_RDONLY) ; short block_num = 0 ; short * const p = ( short * ) ( buf+ 2 ) ; int res = - 1 ; while ( 1 ) { recvfrom ( cfd, buf, 4 , 0 , ( struct sockaddr * ) & sin, & socklen) ; if ( buf[ 1 ] == 4 ) { if ( ntohs ( * p) == 0 || block_num == ntohs ( * p) ) { buf[ 1 ] = 3 ; res = read ( fd, buf+ 4 , 512 ) ; * p = htons ( ++ block_num) ; size = res + 4 ; if ( res == 0 ) { break ; } else { sendto ( cfd, buf, size, 0 , ( struct sockaddr * ) & sin, sizeof ( sin) ) ; } } else { buf[ 1 ] = 3 ; sendto ( cfd, buf, size, 0 , ( struct sockaddr * ) & sin, sizeof ( sin) ) ; } } else { printf ( "未知错误,错误码: %d\n" , buf[ 3 ] ) ; close ( fd) ; close ( cfd) ; return - 1 ; } } close ( fd) ; close ( cfd) ; return 0 ;
}
思维导图