实现 server_client_tcp_文件传输的五个基本功能:
list cd mkdir put(上传) get(下载)
server(服务端)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<dirent.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<pthread.h>
#define N 128
int func_mkdir(int clifd,char *buf)
{
char str[20];
char cmd[5];
char name[20];
sscanf(buf,"%s%s",cmd,name);
int ret = mkdir(name,0777);
if (0 == ret)
{
strcpy(str,"创建目录成功");
}
else
{
strcpy(str,"创建目录失败");
}
write(clifd,&str,strlen(str)+1);
close(clifd);
return 0;
}
int func_cd(int clifd,char *buf)
{
puts(buf);
char str[20];
char cmd[5];
char name[20];
sscanf(buf,"%s%s",cmd,name);
int ret = chdir(name);
if (0 == ret)
{
strcpy(str,"进入成功\n");
}
if(-1 == ret)
{
strcpy(str,"进入失败\n");
}
write(clifd,&str,strlen(str)+1);
close(clifd);
return 0;
}
int func_list(int clifd,char *buf)
{
DIR* dp;
int ret;
struct dirent * direntp;
dp = opendir("./");
if(dp == NULL)
{
perror("opendir");
return -1;
}
while( (direntp = readdir(dp)) != NULL)
{
if(strncmp(direntp->d_name,".",1) == 0 ) continue;
strcpy(buf,direntp->d_name);
ret = write(clifd,buf,N);
if(ret < 0)
{
perror("write");
return -1;
}
}
close(clifd);
return 0;
}
int func_get(int clifd,char *buf)
{
int ret,fd,nbytes;
fd = open(buf+4,O_RDWR);
if(fd < 0)
{
perror("open");
return -1;
}
while( (nbytes= read(fd,buf,N)) > 0)
{
ret = write(clifd,buf,nbytes);
if(ret < 0)
{
perror("write");
return -1;
}
}
close(clifd);
return 0;
}
int func_put(int clifd,char *buf)
{
int ret,fd,nbytes;
fd = open(buf+4,O_RDWR|O_CREAT|O_TRUNC,0664);
if(fd < 0)
{
perror("open");
return -1;
}
while( (nbytes= read(clifd,buf,N)) > 0)
{
ret = write(fd,buf,nbytes);
if(ret < 0)
{
perror("write");
return -1;
}
}
close(clifd);
close(fd);
return 0;
}
void* start_run(void* arg)
{
int clifd =*(int*)arg;
char buf[1024]={};
for(;;)
{
int ret = read(clifd,buf,N);
if(ret < 0)
{
printf("read");
return 0;
}
printf(">>>用户指令 :%s\n",buf);
if( strncmp(buf,"list",4) == 0 )
{
func_list(clifd,buf);
}
else if( strncmp(buf,"get",3) == 0 )
{
func_get(clifd,buf);
}
else if( strncmp(buf,"put",3) == 0 )
{
func_put(clifd,buf);
}
else if( strncmp(buf,"mkdir",5) == 0 )
{
func_mkdir(clifd,buf);
}
else if( strncmp(buf,"cd",2) == 0 )
{
func_cd(clifd,buf);
}
pause();
}
}
int main()
{
printf("服务器创建socket\n");
char buf[N];
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd < 0)
{
perror("socket");
return -1;
}
printf("准备地址...\n");
struct sockaddr_in myaddr;
myaddr.sin_family = AF_INET ;
myaddr.sin_port = htons(8777); //注意端口号的对应
myaddr.sin_addr.s_addr = inet_addr("172.10.20.12"); //ip地址每台计算机不同,须对
printf("绑定socket与地址...\n");
int ret = bind(sockfd,(struct sockaddr *)&myaddr,sizeof(myaddr)) ;
if(ret < 0)
{
perror("bind");
return -1;
}
printf("设置监听...\n");
ret = listen(sockfd,10);
if(ret < 0)
{
perror("listen");
return -1;
}
printf("服务器正在运行,等待客户端连接...\n");
while(1)
{
struct sockaddr_in client;
socklen_t addrlen = sizeof(client);
int clifd = accept(sockfd,(struct sockaddr *)&client,&addrlen) ;
if(clifd < 0)
{
printf("accept");
continue;
}
pthread_t pid;
pthread_create(&pid,NULL,start_run,&clifd);
}
}
client(客户端)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<getch.h>
#define N 128
int func_mkdir(struct sockaddr_in *addr,char * buf)
{
int ret,sockfd,nbytes;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd < 0)
{
perror("socket");
return -1;
}
ret = connect(sockfd,(struct sockaddr *)addr,sizeof(*addr)) ;
if(ret < 0)
{
perror("connect");
return -1;
}
ret = write(sockfd,buf,N);
if(ret < 0)
{
perror("write");
return -1;
}
while( (nbytes= read(sockfd,buf,N)) > 0)
{
printf("%s\n",buf);
}
close(sockfd);
}
int func_cd(struct sockaddr_in *addr,char * buf)
{
int ret,sockfd,nbytes;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd < 0)
{
perror("socket");
return -1;
}
ret = connect(sockfd,(struct sockaddr *)addr,sizeof(*addr)) ;
if(ret < 0)
{
perror("connect");
return -1;
}
ret = write(sockfd,buf,N);
if(ret < 0)
{
perror("write");
return -1;
}
while( (nbytes= read(sockfd,buf,N)) > 0)
{
printf("%s\n",buf);
}
close(sockfd);
}
int func_list(struct sockaddr_in *addr,char * buf)
{
int ret,sockfd,nbytes;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd < 0)
{
perror("socket");
return -1;
}
ret = connect(sockfd,(struct sockaddr *)addr,sizeof(*addr)) ;
if(ret < 0)
{
perror("connect");
return -1;
}
ret = write(sockfd,buf,N);
if(ret < 0)
{
perror("write");
return -1;
}
while( (nbytes= read(sockfd,buf,N)) > 0)
{
printf("%s\n",buf);
}
close(sockfd);
return 0;
}
int func_get(struct sockaddr_in *addr,char * buf)
{
int ret,sockfd,nbytes,fd;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd < 0)
{
perror("socket");
return -1;
}
ret = connect(sockfd,(struct sockaddr *)addr,sizeof(*addr)) ;
if(ret < 0)
{
perror("connect");
return -1;
}
ret = write(sockfd,buf,N);
if(ret < 0)
{
perror("write");
return -1;
}
fd = open(buf+4,O_RDWR|O_CREAT|O_TRUNC,0664);
if(fd < 0)
{
perror("open");
return -1;
}
while( (nbytes= read(sockfd,buf,N)) > 0)
{
ret = write(fd,buf,nbytes);
if(ret < 0)
{
perror("write");
return -1;
}
}
close(sockfd);
return 0;
}
int func_put(struct sockaddr_in *addr,char * buf)
{
int ret,sockfd,nbytes,fd;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd < 0)
{
perror("socket");
return -1;
}
ret = connect(sockfd,(struct sockaddr *)addr,sizeof(*addr)) ;
if(ret < 0)
{
perror("connect");
return -1;
}
ret = write(sockfd,buf,N);
if(ret < 0)
{
perror("write");
return -1;
}
fd = open(buf+4,O_RDWR);
if(fd < 0)
{
perror("open");
return -1;
}
while( (nbytes= read(fd,buf,N)) > 0)
{
ret = write(sockfd,buf,nbytes);
if(ret < 0)
{
perror("write");
return -1;
}
}
close(sockfd);
close(fd);
return 0;
}
int main()
{
char buf[N] = {0};
struct sockaddr_in server;
server.sin_family = AF_INET ;
server.sin_port = htons(8777); //注意端口号的对应
server.sin_addr.s_addr = inet_addr("172.10.20.12"); //ip地址每台计算机不同,须对应
while(1)
{
printf(">:");
fgets(buf,N,stdin);
buf[strlen(buf)-1] = '\0';
if( strncmp(buf,"list",4) == 0 )
{
func_list(&server,buf);
}
else if( strncmp(buf,"get",3) == 0 )
{
func_get(&server,buf);
}
else if( strncmp(buf,"put",3) == 0 )
{
func_put(&server,buf);
}
else if( strncmp(buf,"cd",2) == 0 )
{
printf("请选择要进入的目录:\n");
char name[20]={};
scanf("%s",name);
strcat(buf," ");
strcat(buf,name);
func_cd(&server,buf);
getch();
}
else if( strncmp(buf,"mkdir",5) == 0 )
{ printf("请输入文件名:\n");
char name[20]={};
scanf("%s",name);
strcat(buf," ");
strcat(buf,"./");
strcat(buf,name);
func_mkdir(&server,buf);
getch();
}
else if( strncmp(buf,"quit",4) == 0 )
{
break;
}
else if( strncmp(buf,"exit",4) == 0 )
{
break;
}
else
{
printf("命令错误,请重新输入\n");
}
}
return 0;
}
将服务端与客户端放于两个不同的文件夹
进行测试:
client文件夹:
server文件夹:
运行服务端、客户端:
客户端输入list,出现服务端的目录文件:
客户端输入get test2.txt,下载test2.txt文件:
打开client文件夹,发现test2.txt下载成功:
简单测试完毕…