一、服务端server的建立 :
以共享使用文件 config.h ,使用结构体较为方便 :
定义一些命令的宏,有兴趣后续可添加其他:
#define LS 0
#define GET 1
#define PWD 2
#define IFGO 3
#define LCD 4
#define LLS 5
#define CD 6
#define PUT 7
#define QUIT 8
#define DOFILE 9
struct Message
{
int type;
char data[ 1024 ] ;
char msgbuf[ 128 ] ;
} ;
(1) 设置登录账户和密码功能
void ID_and_Key ( )
{
char * p = NULL ;
int key;
p = ( char * ) malloc ( sizeof ( char ) * 128 ) ;
printf ( "Please scanf you ID :" ) ;
scanf ( "%s" , p) ;
printf ( "Please scanf you Key :" ) ;
scanf ( "%d" , & key) ;
if ( ( strcmp ( p, "lz" ) == 0 ) && key == 666 )
{
printf ( "OK!\n" ) ;
}
}
(2) 提取命令的类型 :
int option_cmd ( char * cmd)
{
if ( ! ( strcmp ( "ls" , cmd) ) )
return LS;
if ( ! ( strcmp ( "pwd" , cmd) ) )
return PWD;
if ( ! ( strcmp ( "quit" , cmd) ) )
return QUIT;
if ( strstr ( cmd, "get" ) != NULL )
return GET;
if ( strstr ( cmd, "put" ) != NULL )
return PUT;
if ( strstr ( cmd, "cd" ) != NULL )
return CD;
}
粗略讲解strstr函数功能:
定义:strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main ( )
{
char * str1 = "abcdefghijk" ;
char * str2 = "efg" ;
char * p = NULL ;
p = ( char * ) malloc ( sizeof ( char ) * 128 ) ;
p = strstr ( str1, str2) ;
printf ( "%s\n" , p) ;
return 0 ;
}
输出结果:efghijk
(3)分割字符串,调用CD、get、中需要使用
char * GetDir ( char * pcmd)
{
char * p;
p = strtok ( pcmd, " " ) ;
p = strtok ( NULL , " " ) ;
return p;
}
粗略讲解strtok:
#include <stdio.h>
#include <string.h>
int main ( )
{
char buf[ 20 ] = "liu,zheng,baba" ;
char * q[ 3 ] ;
int i = 0 ;
char * p = buf;
while ( ( q[ i] = strtok ( p, "," ) ) != NULL )
{
i++ ;
p = NULL ;
}
for ( i = 0 ; i< 3 ; i++ )
{
printf ( "q[%d] is : %s\n" , i, q[ i] ) ;
}
return 0 ;
}
结果:
q[0] is : liu
q[1] is : zheng
q[2] is : baba
(4)处理客户端发送的指令,以定义 message_handle 函数为例 :
void message_handle ( struct Message msg, int c_fd)
{
char cmdbuf[ 1024 ] = { 0 } ;
char * file = NULL ;
int file_fd;
printf ( "The scanf cmd is : %s\n" , msg. data) ;
int Cmd = option_cmd ( msg. data) ;
switch ( Cmd)
{
case LS:
case PWD:
msg. type = 0 ;
FILE * p = popen ( msg. data, "r" ) ;
fread ( msg. data, sizeof ( msg. data) , 1 , p) ;
write ( c_fd, & msg, sizeof ( msg) ) ;
break ;
case QUIT:
printf ( "The client always die out!\n" ) ;
printf ( "--------------------------\n" ) ;
printf ( "**************************\n" ) ;
exit ( - 1 ) ;
case CD:
msg. type = 1 ;
char * dir = GetDir ( msg. data) ;
printf ( "The dir is :%s\n" , dir) ;
chdir ( dir) ;
break ;
case GET:
file = GetDir ( msg. data) ;
if ( access ( file, F_OK) == - 1 )
{
strcpy ( msg. data, "Sorry,NO this file" ) ;
write ( c_fd, & msg, sizeof ( msg) ) ;
}
else
{
msg. type = DOFILE;
file_fd = open ( file, O_RDWR) ;
read ( file_fd, cmdbuf, sizeof ( cmdbuf) ) ;
close ( file_fd) ;
strcpy ( msg. data, cmdbuf) ;
write ( c_fd, & msg, sizeof ( msg) ) ;
}
break ;
case PUT:
file_fd = open ( GetDir ( msg. data) , O_RDWR| O_CREAT, 0666 ) ;
write ( file_fd, msg. msgbuf, strlen ( msg. msgbuf) ) ;
close ( file_fd) ;
break ;
}
}
(5)主函数部分 :
int main ( int argc , char * * argv)
{
int server_fd;
int client_fd;
int n_read;
struct Message msg;
struct sockaddr_in s_addr;
struct sockaddr_in c_addr;
memset ( & s_addr, 0 , sizeof ( struct sockaddr_in) ) ;
memset ( & c_addr, 0 , sizeof ( struct sockaddr_in) ) ;
server_fd = socket ( AF_INET, SOCK_STREAM, 0 ) ;
if ( server_fd == - 1 )
{
printf ( "create socket failed!\n" ) ;
exit ( - 1 ) ;
}
s_addr. sin_family = AF_INET;
s_addr. sin_port = htons ( atoi ( argv[ 2 ] ) ) ;
inet_aton ( argv[ 1 ] , & s_addr. sin_addr) ;
bind ( server_fd, ( struct sockaddr * ) & s_addr, sizeof ( struct sockaddr_in) ) ;
listen ( server_fd, 10 ) ;
int len = sizeof ( struct sockaddr_in) ;
ID_and_Key ( ) ;
while ( 1 )
{
client_fd = accept ( server_fd, ( struct sockaddr * ) & c_addr, & len) ;
if ( client_fd == - 1 )
{
perror ( "why accpet failed : " ) ;
exit ( - 1 ) ;
}
printf ( "Connect IP address is : %s\n" , inet_ntoa ( c_addr. sin_addr) ) ;
if ( fork ( ) == 0 )
{
while ( 1 )
{
memset ( msg. data, 0 , sizeof ( msg. data) ) ;
n_read = read ( client_fd, & msg , sizeof ( msg) ) ;
if ( n_read == 0 )
{
printf ( "The client over!\n" ) ;
break ;
}
else if ( n_read == - 1 )
{
printf ( "read failed!\n" ) ;
exit ( - 1 ) ;
}
else if ( n_read > 0 )
{
message_handle ( msg, client_fd) ;
}
}
}
}
close ( server_fd) ;
close ( client_fd) ;
return 0 ;
}
二、客户端client的建立 :
共享文件config.h :
#define LS 0
#define GET 1
#define PWD 2
#define IFGO 3
#define LCD 4
#define LLS 5
#define CD 6
#define PUT 7
#define QUIT 8
#define DOFILE 9
struct Message
{
int type;
char data[ 1024 ] ;
char msgbuf[ 128 ] ;
} ;
(1)接受指令进行分类选择不同返回值 :
int option_cmd ( char * cmd)
{
if ( ! ( strcmp ( "ls" , cmd) ) )
return LS;
if ( ! ( strcmp ( "lls" , cmd) ) )
return LLS;
if ( ! ( strcmp ( "pwd" , cmd) ) )
return PWD;
if ( ! ( strcmp ( "quit" , cmd) ) )
return QUIT;
if ( strstr ( cmd, "get" ) )
return GET;
if ( strstr ( cmd, "put" ) )
return PUT;
if ( ! strcmp ( cmd, "cd" ) )
return CD;
if ( ! strcmp ( cmd, "lcd" ) )
return LCD;
return - 1 ;
}
(2)对指令的字符串进行分割(与服务端有点不同):
char * GetDir ( char * cmd)
{
char * p;
p = strtok ( cmd, " " ) ;
p = strtok ( NULL , " " ) ;
if ( p== NULL )
{
return cmd;
}
return p;
}
(3)指令的分类执行 :
int CmdHandle_option ( struct Message msg, int c_fd)
{
int CMD;
int file_fd;
char * dir = NULL ;
char buf[ 128 ] ;
memset ( buf, '\0' , 128 ) ;
strcpy ( buf, msg. data) ;
char cmdbuf[ 1024 ] ;
dir = GetDir ( buf) ;
CMD = option_cmd ( buf) ;
switch ( CMD)
{
case LS:
case PWD:
msg. type = 0 ;
write ( c_fd, & msg, sizeof ( msg) ) ;
break ;
case CD:
msg. type = 1 ;
write ( c_fd, & msg, sizeof ( msg) ) ;
break ;
case LLS:
system ( "ls" ) ;
break ;
case LCD:
chdir ( dir) ;
break ;
case QUIT:
strcpy ( msg. data, "quit" ) ;
write ( c_fd, & msg, sizeof ( msg) ) ;
close ( c_fd) ;
exit ( - 1 ) ;
case GET:
msg. type = 2 ;
write ( c_fd, & msg, sizeof ( msg) ) ;
break ;
case PUT:
strcpy ( cmdbuf, msg. data) ;
if ( access ( dir, F_OK) == - 1 )
{
printf ( "Sorry ,The %s file not find!\n" , dir) ;
}
else
{
file_fd = open ( dir, O_RDWR) ;
read ( file_fd, msg. msgbuf, sizeof ( msg. msgbuf) ) ;
close ( file_fd) ;
write ( c_fd, & msg, sizeof ( msg) ) ;
}
break ;
}
return CMD;
}
(4)数据的打印处理 :
void message_handle ( struct Message msg, int c_fd)
{
int n_read;
struct Message MSG;
int newfile_fd;
n_read = read ( c_fd, & MSG, sizeof ( MSG) ) ;
if ( n_read == 0 )
{
printf ( "The server is die out !\n" ) ;
exit ( - 1 ) ;
}
else if ( MSG. type == DOFILE)
{
char * file = GetDir ( msg. data) ;
newfile_fd = open ( file, O_RDWR| O_CREAT, 0600 ) ;
write ( newfile_fd, MSG. data, strlen ( MSG. data) ) ;
printf ( "------------>\n" ) ;
fflush ( stdout ) ;
}
else
{
printf ( "=============================\n" ) ;
printf ( "*****************************\n" ) ;
printf ( "\n%s\n" , MSG. data) ;
printf ( "*****************************\n" ) ;
printf ( "=============================\n" ) ;
fflush ( stdout ) ;
}
}
(5)主函数部分 :
int main ( int argc , char * * argv)
{
int client_fd;
int n_read;
struct Message msg;
client_fd = socket ( AF_INET, SOCK_STREAM, 0 ) ;
if ( client_fd == - 1 )
{
printf ( "create socket failed!\n" ) ;
exit ( - 1 ) ;
}
struct sockaddr_in c_addr;
memset ( & c_addr, 0 , sizeof ( struct sockaddr_in) ) ;
c_addr. sin_family = AF_INET;
c_addr. sin_port = htons ( atoi ( argv[ 2 ] ) ) ;
inet_aton ( argv[ 1 ] , & c_addr. sin_addr) ;
if ( connect ( client_fd, ( struct sockaddr * ) & c_addr, sizeof ( struct sockaddr) ) == - 1 )
{
printf ( "The connect failed !\n" ) ;
exit ( - 1 ) ;
}
printf ( "Connect server OK !\n" ) ;
while ( 1 )
{
memset ( msg. data, 0 , sizeof ( msg. data) ) ;
gets ( msg. data) ;
printf ( "--->You scanf cmd is : %s\n" , msg. data) ;
int cmd = CmdHandle_option ( msg, client_fd) ;
if ( cmd > IFGO)
{
printf ( "------------>" ) ;
fflush ( stdout ) ;
continue ;
}
if ( cmd == - 1 )
{
printf ( "The cmd is not find !\n" ) ;
fflush ( stdout ) ;
continue ;
}
message_handle ( msg, client_fd) ;
}
return 0 ;
}
三、以ftpserver.c 和 ftpclient.c 为例子 :
config.h :
#define LS 0
#define GET 1
#define PWD 2
#define IFGO 3
#define LCD 4
#define LLS 5
#define CD 6
#define PUT 7
#define QUIT 8
#define DOFILE 9
struct Message
{
int type;
char data[ 1024 ] ;
char msgbuf[ 128 ] ;
} ;
ftpserver.c :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "config.h"
#include <sys/stat.h>
#include <fcntl.h>
void ID_and_Key ( )
{
char * p = NULL ;
int key;
p = ( char * ) malloc ( sizeof ( char ) * 128 ) ;
printf ( "Please scanf you ID :" ) ;
scanf ( "%s" , p) ;
printf ( "Please scanf you Key :" ) ;
scanf ( "%d" , & key) ;
if ( ( strcmp ( p, "lz" ) == 0 ) && key == 666 )
{
printf ( "OK!\n" ) ;
}
}
int option_cmd ( char * cmd)
{
if ( ! ( strcmp ( "ls" , cmd) ) )
return LS;
if ( ! ( strcmp ( "pwd" , cmd) ) )
return PWD;
if ( ! ( strcmp ( "quit" , cmd) ) )
return QUIT;
if ( strstr ( cmd, "get" ) != NULL )
return GET;
if ( strstr ( cmd, "put" ) != NULL )
return PUT;
if ( strstr ( cmd, "cd" ) != NULL )
return CD;
}
char * GetDir ( char * pcmd)
{
char * p;
p = strtok ( pcmd, " " ) ;
p = strtok ( NULL , " " ) ;
return p;
}
void message_handle ( struct Message msg, int c_fd)
{
char cmdbuf[ 1024 ] = { 0 } ;
char * file = NULL ;
int file_fd;
printf ( "The scanf cmd is : %s\n" , msg. data) ;
int Cmd = option_cmd ( msg. data) ;
switch ( Cmd)
{
case LS:
case PWD:
msg. type = 0 ;
FILE * p = popen ( msg. data, "r" ) ;
fread ( msg. data, sizeof ( msg. data) , 1 , p) ;
write ( c_fd, & msg, sizeof ( msg) ) ;
break ;
case QUIT:
printf ( "The client always die out!\n" ) ;
printf ( "--------------------------\n" ) ;
printf ( "**************************\n" ) ;
exit ( - 1 ) ;
case CD:
msg. type = 1 ;
char * dir = GetDir ( msg. data) ;
printf ( "The dir is :%s\n" , dir) ;
chdir ( dir) ;
break ;
case GET:
file = GetDir ( msg. data) ;
if ( access ( file, F_OK) == - 1 )
{
strcpy ( msg. data, "Sorry,NO this file" ) ;
write ( c_fd, & msg, sizeof ( msg) ) ;
}
else
{
msg. type = DOFILE;
file_fd = open ( file, O_RDWR) ;
read ( file_fd, cmdbuf, sizeof ( cmdbuf) ) ;
close ( file_fd) ;
strcpy ( msg. data, cmdbuf) ;
write ( c_fd, & msg, sizeof ( msg) ) ;
}
break ;
case PUT:
file_fd = open ( GetDir ( msg. data) , O_RDWR| O_CREAT, 0666 ) ;
write ( file_fd, msg. msgbuf, strlen ( msg. msgbuf) ) ;
close ( file_fd) ;
break ;
}
}
int main ( int argc , char * * argv)
{
int server_fd;
int client_fd;
int n_read;
struct Message msg;
struct sockaddr_in s_addr;
struct sockaddr_in c_addr;
memset ( & s_addr, 0 , sizeof ( struct sockaddr_in) ) ;
memset ( & c_addr, 0 , sizeof ( struct sockaddr_in) ) ;
server_fd = socket ( AF_INET, SOCK_STREAM, 0 ) ;
if ( server_fd == - 1 )
{
printf ( "create socket failed!\n" ) ;
exit ( - 1 ) ;
}
s_addr. sin_family = AF_INET;
s_addr. sin_port = htons ( atoi ( argv[ 2 ] ) ) ;
inet_aton ( argv[ 1 ] , & s_addr. sin_addr) ;
bind ( server_fd, ( struct sockaddr * ) & s_addr, sizeof ( struct sockaddr_in) ) ;
listen ( server_fd, 10 ) ;
int len = sizeof ( struct sockaddr_in) ;
ID_and_Key ( ) ;
while ( 1 )
{
client_fd = accept ( server_fd, ( struct sockaddr * ) & c_addr, & len) ;
if ( client_fd == - 1 )
{
perror ( "why accpet failed : " ) ;
exit ( - 1 ) ;
}
printf ( "Connect IP address is : %s\n" , inet_ntoa ( c_addr. sin_addr) ) ;
if ( fork ( ) == 0 )
{
while ( 1 )
{
memset ( msg. data, 0 , sizeof ( msg. data) ) ;
n_read = read ( client_fd, & msg , sizeof ( msg) ) ;
if ( n_read == 0 )
{
printf ( "The client over!\n" ) ;
break ;
}
else if ( n_read == - 1 )
{
printf ( "read failed!\n" ) ;
exit ( - 1 ) ;
}
else if ( n_read > 0 )
{
message_handle ( msg, client_fd) ;
}
}
}
}
close ( server_fd) ;
close ( client_fd) ;
return 0 ;
}
ftpclient.c :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "config.h"
#include <sys/stat.h>
#include <fcntl.h>
int option_cmd ( char * cmd)
{
if ( ! ( strcmp ( "ls" , cmd) ) )
return LS;
if ( ! ( strcmp ( "lls" , cmd) ) )
return LLS;
if ( ! ( strcmp ( "pwd" , cmd) ) )
return PWD;
if ( ! ( strcmp ( "quit" , cmd) ) )
return QUIT;
if ( strstr ( cmd, "get" ) )
return GET;
if ( strstr ( cmd, "put" ) )
return PUT;
if ( ! strcmp ( cmd, "cd" ) )
return CD;
if ( ! strcmp ( cmd, "lcd" ) )
return LCD;
return - 1 ;
}
char * GetDir ( char * cmd)
{
char * p;
p = strtok ( cmd, " " ) ;
p = strtok ( NULL , " " ) ;
if ( p== NULL )
{
return cmd;
}
return p;
}
int CmdHandle_option ( struct Message msg, int c_fd)
{
int CMD;
int file_fd;
char * dir = NULL ;
char buf[ 128 ] ;
memset ( buf, '\0' , 128 ) ;
strcpy ( buf, msg. data) ;
char cmdbuf[ 1024 ] ;
dir = GetDir ( buf) ;
CMD = option_cmd ( buf) ;
switch ( CMD)
{
case LS:
case PWD:
msg. type = 0 ;
write ( c_fd, & msg, sizeof ( msg) ) ;
break ;
case CD:
msg. type = 1 ;
write ( c_fd, & msg, sizeof ( msg) ) ;
break ;
case LLS:
system ( "ls" ) ;
break ;
case LCD:
chdir ( dir) ;
break ;
case QUIT:
strcpy ( msg. data, "quit" ) ;
write ( c_fd, & msg, sizeof ( msg) ) ;
close ( c_fd) ;
exit ( - 1 ) ;
case GET:
msg. type = 2 ;
write ( c_fd, & msg, sizeof ( msg) ) ;
break ;
case PUT:
strcpy ( cmdbuf, msg. data) ;
if ( access ( dir, F_OK) == - 1 )
{
printf ( "Sorry ,The %s file not find!\n" , dir) ;
}
else
{
file_fd = open ( dir, O_RDWR) ;
read ( file_fd, msg. msgbuf, sizeof ( msg. msgbuf) ) ;
close ( file_fd) ;
write ( c_fd, & msg, sizeof ( msg) ) ;
}
break ;
}
return CMD;
}
void message_handle ( struct Message msg, int c_fd)
{
int n_read;
struct Message MSG;
int newfile_fd;
n_read = read ( c_fd, & MSG, sizeof ( MSG) ) ;
if ( n_read == 0 )
{
printf ( "The server is die out !\n" ) ;
exit ( - 1 ) ;
}
else if ( MSG. type == DOFILE)
{
char * file = GetDir ( msg. data) ;
newfile_fd = open ( file, O_RDWR| O_CREAT, 0600 ) ;
write ( newfile_fd, MSG. data, strlen ( MSG. data) ) ;
printf ( "------------>\n" ) ;
fflush ( stdout ) ;
}
else
{
printf ( "=============================\n" ) ;
printf ( "*****************************\n" ) ;
printf ( "\n%s\n" , MSG. data) ;
printf ( "*****************************\n" ) ;
printf ( "=============================\n" ) ;
fflush ( stdout ) ;
}
}
int main ( int argc , char * * argv)
{
int client_fd;
int n_read;
struct Message msg;
client_fd = socket ( AF_INET, SOCK_STREAM, 0 ) ;
if ( client_fd == - 1 )
{
printf ( "create socket failed!\n" ) ;
exit ( - 1 ) ;
}
struct sockaddr_in c_addr;
memset ( & c_addr, 0 , sizeof ( struct sockaddr_in) ) ;
c_addr. sin_family = AF_INET;
c_addr. sin_port = htons ( atoi ( argv[ 2 ] ) ) ;
inet_aton ( argv[ 1 ] , & c_addr. sin_addr) ;
if ( connect ( client_fd, ( struct sockaddr * ) & c_addr, sizeof ( struct sockaddr) ) == - 1 )
{
printf ( "The connect failed !\n" ) ;
exit ( - 1 ) ;
}
printf ( "Connect server OK !\n" ) ;
while ( 1 )
{
memset ( msg. data, 0 , sizeof ( msg. data) ) ;
gets ( msg. data) ;
printf ( "--->You scanf cmd is : %s\n" , msg. data) ;
int cmd = CmdHandle_option ( msg, client_fd) ;
if ( cmd > IFGO)
{
printf ( "------------>" ) ;
fflush ( stdout ) ;
continue ;
}
if ( cmd == - 1 )
{
printf ( "The cmd is not find !\n" ) ;
fflush ( stdout ) ;
continue ;
}
message_handle ( msg, client_fd) ;
}
return 0 ;
}