转自:https://blog.csdn.net/xiaopangzi313/article/details/9122975

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaopangzi313/article/details/9122975

项目功能:实现服务器与客户端的下载与上传,及linux系统下的tftp功能

项目名称:tftp--实现服务器与客户端的下载与上传

开发环境:linux /C

开发工具:GCC/GDB

网络协议:TCP/IP

补充说明:程序中默认server端有upload文件夹用以接收client端上传的数据,client端有download文件夹用以下载server端的文件

开发流程:

编译流程:

1.cc    server.c  -o server

2.cc  client.c  -o client

运行l流程:

1.  ./server  192.168.1.207(server ip)  8888(port)

2. ./client    192.168.1.207  8888

调试效果:

client 端

server 端

1.server.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<signal.h>
#include<errno.h>
#include <dirent.h>

typedef struct {
char cmd[10];
int size;
char buf[1024];
}MSG;
MSG msg;
enum{list,get,put};
int do_list(int connect_fd)
{

char buf[1024];
int n;
int fd;
DIR *pdir;
struct dirent *pdirent;
if((pdir = opendir(".")) == NULL)
{
perror("Fail to open directory ");
exit(EXIT_FAILURE);
}
while((pdirent = readdir(pdir)) != NULL)
{
if(pdirent->d_name[0] == '.' )
continue;
strcpy(msg.buf,pdirent->d_name);
msg.size = strlen(msg.buf);
msg.size = send(connect_fd,&msg,sizeof(MSG),0);
}
msg.size = 0;
send(connect_fd,&msg,sizeof(MSG),0);
puts("send list successfully");
return 0;
}

int do_get(int connect_fd)
{
char filename[10];
int n;
int fd;
struct stat fileinfo;
if(recv(connect_fd,&msg,sizeof(MSG),0) < 0)
{
perror("fail to recv");
exit(EXIT_FAILURE);
}

if(stat(msg.buf,&fileinfo) < 0)
{
perror("fail to stat");
msg.size = -1;
strcpy(msg.buf,strerror(errno));
send(connect_fd,&msg,sizeof(MSG),0);
return -1;
}
msg.size = fileinfo.st_size;
strcpy(filename,msg.buf);

puts("***********************");
printf("send file size : %d\n",msg.size);
printf("send filename : %s\n",msg.buf);
puts("***********************");

if(send(connect_fd,&msg,sizeof(MSG),0) < 0)
{
perror("fail to recv");
exit(EXIT_FAILURE);
}

if((fd = open(msg.buf,O_RDONLY)) < 0)
{
fprintf(stderr,"Fail to open %s, %s\n",msg.buf,strerror(errno));
exit(EXIT_FAILURE);
}

while(1)
{
msg.size = read(fd, msg.buf,sizeof(msg.buf));
send(connect_fd,&msg,sizeof(MSG),0);
if(msg.size == 0)
break;
}
printf("send file %s successfully\n",filename);

return 0;
}
int do_put(int connect_fd)
{
char buf[1024];
int n;
int fd;
if(recv(connect_fd,&msg,sizeof(msg),0) <= 0)
{
perror("fail to recv");
exit(EXIT_FAILURE);
}

puts("**********************************");
printf("upload filename : %s\n",msg.buf);
printf("size: %d\n",msg.size);
puts("**********************************");

strcpy(buf,"./upload/");
strcat(buf,msg.buf);
if((fd = open(buf,O_WRONLY | O_CREAT | O_TRUNC,0666)) < 0)
{
perror("Fail to accept");
exit(EXIT_FAILURE);
}
ftruncate(fd,msg.size);

while(1)
{
recv(connect_fd,&msg,sizeof(MSG),0);
write(fd,msg.buf,msg.size);
if(msg.size == 0)
break;
}
printf("send file successfully!\n");

exit(EXIT_SUCCESS);

}
int getcmd(char *pcmd)
{
if(strcmp(pcmd,"list") == 0)
return 0;
if(strcmp(pcmd,"get") == 0)
return 1;
if(strcmp(pcmd,"put") == 0)
return 2;
}
void do_task(int connect_fd,char *cmd)
{
MSG msg;

switch(getcmd(cmd))
{
case put:
printf("recv file from client...\n");
do_put(connect_fd);
break;
case get:
printf("send file to client...\n");
do_get(connect_fd);
break;
case list:
printf("send file list to client...\n");
do_list(connect_fd);
break;
default :
break;
}

return;
}
int do_client(int connect_fd)
{
MSG msg;
int n;
while(1)
{
if((n =recv(connect_fd,&msg,sizeof(msg),0) )< 0)
{
perror("fail to recv");
exit(EXIT_FAILURE);
}
if(n == 0)
break;

do_task(connect_fd,msg.cmd);

}

exit(EXIT_FAILURE);
}
void signal_handler(int signum)
{
waitpid(-1,NULL,WNOHANG);
return;
}
int main(int argc, const char *argv[])
{
pid_t pid;
int listen_fd;
int connect_fd;
socklen_t addrlen;
struct sockaddr_in peer_addr;
struct sockaddr_in server_addr;
if(argc < 0)
{
perror("fail to argc");
exit(EXIT_FAILURE);

}
if(signal(SIGCHLD,signal_handler) == SIG_ERR)
{
perror("fail to signal");
exit(EXIT_FAILURE);
}
if((listen_fd = socket(AF_INET,SOCK_STREAM,0) )< 0)
{
perror("fail to socket");
exit(EXIT_FAILURE);
}
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(atoi(argv[2]));
server_addr.sin_addr.s_addr =inet_addr(argv[1]);
if(bind(listen_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0) //描述本机端口和IP,要知道数据包发往哪个进程
{
perror("Fail to bind");
exit(EXIT_FAILURE);
}

if(listen(listen_fd,8 ) < 0)//监听连接的套接字,接收各客户端的请求,返回监听套接字文件描述符
{
perror("Fail to listen");
exit(EXIT_FAILURE);
}
puts("listening ...");
addrlen = sizeof(peer_addr);
while(1)
{
if((connect_fd = accept(listen_fd,(struct sockaddr *)&peer_addr,&addrlen)) < 0)
{
perror("Fail to accept");//提取客户发过来的请求,返回新的已连接的套接字文件描述符
exit(EXIT_FAILURE);
}
puts("*************************");
printf("IP : %s\n",inet_ntoa(peer_addr.sin_addr));
printf("PORT : %d\n",ntohs(peer_addr.sin_port));
puts("*************************");
if((pid = fork()) < 0)
{
perror("Fail to listen");
exit(EXIT_FAILURE);
}
if(pid == 0)
{
do_client(connect_fd);
}
close(connect_fd);
}
exit(EXIT_FAILURE);
}

2.client.c

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

typedef struct {
char cmd[10];
int size;
char buf[1024];
}MSG;

enum{list,get,put};
int do_list(client_fd,pname)
{
MSG msg;
int fd;
while(1)
{
recv(client_fd,&msg,sizeof(MSG),0);
if(msg.size == 0)
break;
printf("%s\n",msg.buf);
}
puts("get list successfully");
return 0;
}

int do_get(int client_fd,char *filename)
{
MSG msg;
int fd;
char buf[1024];
strcpy(msg.buf,filename);

if(send (client_fd,&msg,sizeof(MSG),0) < 0)
{
perror("Fail to send");
exit(EXIT_FAILURE);
}

recv(client_fd,&msg,sizeof(MSG),0);
if(msg.size < 0)
{
printf("Error :%s \n",msg.buf);
return -1;
}

puts("***********************");
printf(" download file size : %d\n",msg.size);
printf(" download filename : %s\n",msg.buf);
puts("***********************");

strcpy(buf,"./download/");
strcat(buf,msg.buf);
if((fd = open(buf,O_WRONLY | O_CREAT | O_TRUNC,0666)) < 0)
{
fprintf(stderr,"Fail to open %s,%s\n",buf,strerror(errno));
exit(EXIT_FAILURE);
}

ftruncate(fd, msg.size);

while(1)
{
recv(client_fd,&msg,sizeof(MSG),0);
if(msg.size == 0)
break;
write(fd,msg.buf,msg.size);
}
printf("download file %s successfully\n",filename);
return 0;
}
int do_put(int client_fd,char *filename)
{
MSG msg;
int fd;
int n;
if((fd = open(filename,O_RDONLY)) < 0)
{
perror("Fail to open");
exit(EXIT_FAILURE);

}
msg.size = lseek(fd,0,SEEK_END);
strcpy(msg.buf,filename);
lseek(fd,0,SEEK_SET);

puts("**********************************");
printf("filename : %s\n",msg.buf);
printf("size :%d\n",msg.size);
puts("**********************************");

if(send(client_fd,&msg,sizeof(MSG),0) < 0)
{
perror("Fail to send");
exit(EXIT_FAILURE);
}
while(1)
{

msg.size = read(fd,msg.buf,sizeof(msg.buf));
if(send(client_fd,&msg,sizeof(MSG),0) < 0)
{
perror("Fail to read");
exit(EXIT_FAILURE);
}
if(msg.size == 0)
break;
}
printf("upload file successfully!\n");

return 0;
}
int getcmd(char *pcmd)
{
if(strcmp(pcmd,"list") == 0)
return 0;
if(strcmp(pcmd,"get") == 0)
return 1;
if(strcmp(pcmd,"put") == 0)
return 2;
}
int do_task(char *pcmd,char *pname,int client_fd)
{
MSG msg;
char buf[1024];
int fd;
switch(getcmd(pcmd))
{
case list:
printf("get file list from the server ...\n");
strcpy(msg.cmd,pcmd);

if(send(client_fd,&msg,sizeof(MSG),0) < 0)
{
perror("FAIL to send");
exit(EXIT_FAILURE);
}
do_list(client_fd,pname);
break;
case get:
printf("file %s is downloading from server ...\n",pname);
strcpy(msg.cmd , pcmd);
if(send(client_fd,&msg,sizeof(MSG),0) < 0)
{
perror("FAIL to send");
exit(EXIT_FAILURE);
}
do_get(client_fd,pname);
break;
case put:
printf(" file %s is uploading to server ...\n",pname);
strcpy(msg.cmd,pcmd);
if(send(client_fd,&msg,sizeof(MSG),0) < 0)
{
perror("Fail to send!");
exit(EXIT_FAILURE);
}
do_put(client_fd,pname);
break;

default:
break;

}
return 0;

}
int main(int argc, const char *argv[])
{
MSG msg;
char buf[1024];
char *pname,*pcmd;
int client_fd;
pid_t pid;
int connect_fd;
socklen_t addrlen;
struct sockaddr_in server_addr;

if((client_fd = socket(AF_INET,SOCK_STREAM,0) )< 0)
{
perror("fail to socket");
exit(EXIT_FAILURE);
}
memset(&server_addr,0,sizeof(server_addr));

server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr =inet_addr(argv[1]);
server_addr.sin_port = htons(atoi(argv[2]));

if(connect(client_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0)
{
perror("Fail to accept");
exit(EXIT_FAILURE);
}

while(1)
{
printf("tftp>");
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf) -1] = '\0';
if(strncmp(buf,"quit",4) == 0)
break;
pcmd = strtok(buf," ");
pname = strtok(NULL," ");
do_task(pcmd,pname,client_fd);
}
exit(EXIT_FAILURE);

return 0;
}

---------------------
作者:xiaopangzi313
来源:CSDN
原文:https://blog.csdn.net/xiaopangzi313/article/details/9122975
版权声明:本文为博主原创文章,转载请附上博文链接!

tftp--实现服务器与客户端的下载与上传【转】的更多相关文章

  1. 网络编程 UDP协议 TCP局域网客户端与服务端上传下载电影示例

    UDP协议 (了解) 称之为数据包协议,又称不可靠协议. 特点: 1) 不需要建立链接. 2) 不需要知道对方是否收到. 3) 数据不安全 4) 传输速度快 5)能支持并发 6) 不会粘包 7) 无需 ...

  2. 编写Java程序,实现客户端向服务端上传文件的功能

    查看本章节 查看作业目录 需求说明: 实现客户端向服务端上传文件的功能 当启动服务端后,运行客户端程序,系统提示客户在客户端输入上传文件的完整路径.当客户在客户端输入完成后,服务端实现文件上传 实现思 ...

  3. iOS开发——网络篇——NSURLSession,下载、上传代理方法,利用NSURLSession断点下载,AFN基本使用,网络检测,NSURLConnection补充

    一.NSURLConnection补充 前面提到的NSURLConnection有些知识点需要补充 NSURLConnectionDataDelegate的代理方法有一下几个 - (void)conn ...

  4. ios开发之网络数据的下载与上传

    要实现网络数据的下载与上传,主要有三种方式 > NSURLConnection  针对少量数据,使用“GET”或“POST”方法从服务器获取数据,使用“POST”方法向服务器传输数据; > ...

  5. 重新想象 Windows 8.1 Store Apps (89) - 通信的新特性: 下载数据, 上传数据, 上传文件

    [源码下载] 重新想象 Windows 8.1 Store Apps (89) - 通信的新特性: 下载数据, 上传数据, 上传文件 作者:webabcd 介绍重新想象 Windows 8.1 Sto ...

  6. iOS开发——网络Swift篇&NSURLSession加载数据、下载、上传文件

    NSURLSession加载数据.下载.上传文件   NSURLSession类支持三种类型的任务:加载数据.下载和上传.下面通过样例分别进行介绍.   1,使用Data Task加载数据 使用全局的 ...

  7. [转载]ASP.NET Core文件上传与下载(多种上传方式)

    ASP.NET Core文件上传与下载(多种上传方式)   前言 前段时间项目上线,实在太忙,最近终于开始可以研究研究ASP.NET Core了. 打算写个系列,但是还没想好目录,今天先来一篇,后面在 ...

  8. Android开发 retrofit下载与上传

    前言 此博客只讲解retrofit下载与上传的使用,其实与其说是retrofit的下载与上传还不如说,依然是Okhttp的下载与上传.如果你需要了解retrofit入门请查看这篇博客(此博客不在详细讲 ...

  9. SVN服务器和客户端的下载和安装

    一.SVN服务器VisualSVN下载和安装 当前版本:4.1.3下载地址:https://www.visualsvn.com/server/download/下载下来的文件:VisualSVN-Se ...

随机推荐

  1. 关于win7+VS2017环境下的opencv-contirb配置的一个坑

    问题出现背景: 由于课题需要用到SURF detector, 我依照网上的一下教程,把opencv-contrib的配置了一遍.但是,当我写了一个小demo来测试模块是否能正常使用的时候,程序能正常编 ...

  2. 菜鸟学python之程序初体验

    作业来源:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2684 1.字符串操作: 解析身份证号:生日.性别.出生地等. def id ...

  3. Echarts学习之路2(基本配置项)

    title:标题组件,包含主标题和副标题. title:{ text:"",//主标题 link:"",//主标题文本超链接 target:"&quo ...

  4. 【刷题】Git工作流-相关知识点

    参考资料:[学习总结]Git学习-GIT工作流-千峰教育(来自B站) 1-Git工作流 GitFlow流五大分支: 主干分支 热修复分支 预发布分支 开发分支 功能分支 GitFlow 工作流定义了一 ...

  5. 目录树生成工具treer

    安装方法 $ npm install treer -g 生成结构 $ treer Desktop├─.DS_Store├─.localized├─dir2 | ├─file3 | └file4├─di ...

  6. centos7之zabbix3.2代理(zabbix-proxy)搭建

    zabbix的强大之处也在于它是分布式监控系统,对于多机房大集群情况下,肯定不是一台zabbix-server服务器来进行信息的收集等工作,就要用到代理了.在记录zabbix-proxy之前,要系统的 ...

  7. python+ffmpeg切割视频

    什么是ffmpeg 1.1 简介 FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件).它提供了录制.转换以及流化音视频的完整解决方案.它包 ...

  8. jquery笔记整理

    01-jquery简介 1)功能:     ·html元素选取     ·Html元素操作     ·Css操作     ·Html事件函数     ·JavaScript特效和动画     ·DOM ...

  9. js手机滑块模仿

    点击文本框滑动选值 手机屏幕上的上下翻滚菜单使用JS实现.经过十几个小时的折磨,终于有了最初版本.实现办法如下描述: 一.要求和方法 1.一个input输入框,点击后弹出一个翻滚菜单盖在其上,翻滚选好 ...

  10. 【洛谷P1402】酒店之王

    题目大意:有三个集合 \(P,Q,N\),P 与 N 集合之间存在一些有向边,N 与 Q 集合之间存在一些有向边.在三个集合中每个点最多只能利用一次的前提下,求最多能利用多少N 集合中的点,使得 \( ...