总体需求:

编写tcp文件服务器和客户端。客户端可以上传和下载文件。

================================================

分解需求

客户端功能描述:

1)要求支持以下命令:

help: 显示客户端所有命令和说明, 在本地实现即可,help的内容不需要从服务器传回。

list: 显示服务器端可下载文件列表,列表内容需要从服务器端传回。

get : 根据下载指定文件,只包含文件名,如果出现"/"等字符任务是路径,不予支持;下载后的文件存放在当前工作路径下即可。

put : 上传文件 必须为客户端本机的合法路径,客户端搜索到文件后推送给服务器

quit: 退出客户端

2)客户端启动后可以反复输入命令,除非用户输入quit才会退出。

3) 每次命令(list/get/put)建立一个连接,命令执行完毕后关闭该连接。

服务器端功能:

1)文件服务器不要求支持并发,同时只支持一个连接,即一个客户端发起的一次命令。一次命令执行完毕后关闭连接并继续等待下一次连接请求。

2)文件服务器启动后一直执行,除非被人为强制关闭。

3)文件服务器端需要设定一个目录用于存放所有的文件,该目录路径不支持可配置,且该目录不要求再包含子目录。称其为"文件存放目录"。

4)对list服务,服务器端从"文件存放目录"下列举出所有的文件名称并发送给客户端。

5)对get服务,服务器根据用户指定的文件名缺省从"文件存放目录"搜索该文件并推送文件到客户端,推送不会删除原服务器上的文件。

6)对put服务,服务器将用户推送的文件存储到"文件存放目录",如果存在同名的文件则拒绝。

7)若执行命令和传输过程中发生错误,关闭当前连接并进入等待下一个连接。

=================================================

提示:

请在编码前仔细设计一个简单的应用层协议规定客户端和服务器端之间命令传输的请求和应答流程和格式。

二。参考代码:

1.服务器端参考代码

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define N 128

#define PORT_NUM 8888

typedef struct sockaddr SA;

void ProcessList(int connfd)

{

char buf[N];

DIR *mydir;

struct dirent *myitem;

mydir = opendir(".");

while((myitem = readdir(mydir)) != NULL){

if((strcmp(myitem->d_name, ".") == 0) || (strcmp(myitem->d_name, "..") == 0))

continue;

strcpy(buf, myitem->d_name);

send( connfd, buf, N, 0);

}

close(connfd);

return;

}

void ProcessGet(int connfd, char buf[])

{

int fd,nbyte;

if(( fd = open(buf+1, O_RDONLY))

fprintf(stderr, "fail to open %s: %s\n",buf+1,strerror(errno));

buf[0] = 'N';

send(connfd, buf, N, 0);

return;

}

buf[0] = 'Y';

send(connfd, buf, N, 0);

while(( nbyte = read( fd, buf, N)) > 0){

send(connfd, buf, nbyte, 0);

}

close(connfd);

return;

}

void ProcessPut(int connfd, char buf[])

{

int fd, nbyte;

if(( fd = open(buf+1, O_WRONLY | O_CREAT | O_TRUNC, 0666))

printf("fail to create %s on server\n",buf+1);

return;

}

while(( nbyte = recv( connfd, buf, N, 0)) > 0){

write(fd, buf, nbyte);

}

close(fd);

return;

}

int main(int argc, char *argv[])

{

int listenfd, connfd;

int optval = 1;

char buf[N];

struct sockaddr_in server_addr;

if(( listenfd = socket( AF_INET, SOCK_STREAM, 0))

fprintf(stderr, "fail to socket: %s\n",strerror(errno));

exit(-1);

}

#ifdef _DEBUG_

printf("socket is %d\n", listenfd);

#endif

memset(&server_addr, 0, sizeof(server_addr));

server_addr.sin_family = AF_INET;

server_addr.sin_port = htons(PORT_NUM);

server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

if( bind( listenfd, (SA *)(&server_addr), sizeof(server_addr))

perror("fail to bind");

exit(-1);

}

listen( listenfd, 5);

while(1){

if(( connfd = accept(listenfd, NULL, NULL))

perror("fail to accept");

break;

}

recv( connfd, buf, N, 0);

switch(buf[0]){

case 'L': ProcessList(connfd);

break;

case 'G': ProcessGet(connfd, buf);

break;

case 'P': ProcessPut(connfd, buf);

break;

default: printf("Input ");

}

close(connfd);

}

return 0;

}

2.客户端参考代码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define N 128

#define PORT_NUM 8888

typedef struct sockaddr SA;

void PrintHelp()

{

printf("help: display help info\n");

printf("list: get file list of server\n");

printf("get : get \n");

printf("put : put \n");

printf("quit: quit the client\n");

return;

}

void ProcessList(struct sockaddr_in server_addr)

{

int sockfd, nbyte;

char buf[N];

if(( sockfd = socket( AF_INET, SOCK_STREAM, 0))

printf("fail to list\n");

return;

}

if( connect(sockfd, (SA *)(&server_addr), sizeof(server_addr))

printf("fail to connect server\n");

goto ERROR_1;

}

strcpy(buf, "L");

send(sockfd, buf, N, 0);

while(( nbyte = recv( sockfd, buf, N, 0)) != 0){

printf("%s\n",buf);

}

ERROR_1:

close(sockfd);

return;

}

void ProcessGet(struct sockaddr_in server_addr, char command[])

{

int sockfd, nbyte, fd;

char buf[N];

if(( sockfd = socket( AF_INET, SOCK_STREAM, 0))

printf("fail to get\n");

return;

}

if( connect( sockfd, (SA *)(&server_addr), sizeof(server_addr))

printf("fail to connect server\n");

goto ERROR_2;

}

sprintf(buf, "G%s", command+4);

send(sockfd, buf, N, 0);

recv(sockfd, buf, N, 0);

if(buf[0] == 'N'){

printf("No such file on server\n");

goto ERROR_2;

}

if(( fd = open(command+4, O_WRONLY | O_CREAT | O_TRUNC, 0666))

printf("fail to create local file %s\n",command+4);

goto ERROR_2;

}

while(( nbyte = recv(sockfd, buf, N, 0)) > 0){

write(fd, buf, nbyte);

}

close(fd);

ERROR_2:

close(sockfd);

return;

}

void ProcessPut(struct sockaddr_in server_addr, char command[])

{

int sockfd, fd, nbyte;

char buf[N];

if(( sockfd = socket( AF_INET, SOCK_STREAM, 0))

printf("fail to get\n");

return;

}

if( connect(sockfd,(SA *)(&server_addr),sizeof(server_addr))

printf("fail to connect server\n");

goto ERROR_3;

}

if((fd = open(command+4, O_RDONLY))

printf("fail to open %s\n",command+4);

goto ERROR_3;

}

sprintf(buf, "P%s", command+4);

send(sockfd, buf, N, 0);

while(( nbyte = read(fd, buf, N)) > 0){

send(sockfd, buf, nbyte, 0);

}

close(fd);

ERROR_3:

close(sockfd);

return;

}

int main(int argc, char *argv[])

{

int sockfd, fd, nbyte;

char command[32];

struct sockaddr_in server_addr;

if(argc

printf("Usage: %s  \n",argv[0]);

exit(-1);

}

if(( sockfd = socket( AF_INET, SOCK_STREAM, 0))

fprintf(stderr, "fail to socket: %s\n", strerror(errno));

exit(-1);

}

#ifdef _DEBUG_

printf("socket is %d\n",sockfd);

#endif

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]);

//server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

while(1){

printf("");

fgets(command, 32, stdin);

command[strlen(command)-1] = '\0';

if(strcmp( command, "help") == 0){

PrintHelp();

}

else if(strcmp( command, "list") == 0){

ProcessList(server_addr);

}

else if(strncmp( command, "get", 3) == 0){

ProcessGet(server_addr, command);

}

else if(strncmp( command, "put", 3) == 0){

ProcessPut(server_addr, command);

}

else if(strcmp( command, "quit") == 0){

printf("Bye\n");

break;

}

else{

printf("Wrong command, 'help' for command list.\n");

}

}

return 0;

}

3.验证结果(ubuntu14.04)

linux tcp文件分包_Linux c实现一个tcp文件服务器和客户端相关推荐

  1. linux tcp文件分包_Linux网络监控工具大点兵

    网络通讯Linux中最基本基本的功能之一,很多是时候我们需要获取Linux的网络信息.Linux中存在很多网络监控工具,本文就给大家介绍一下,Linux常见的网络监控工具. Netstat Netst ...

  2. linux tcp文件分包_Linux内核参数优化

    前言: 1:介绍下linux内核的整个知识体系,(学会它,你肯定对linux内核有不一样的理解.) 2:谈谈Linux内核参数优化 一:linux内核技术点 Linux内核知识体系分为五个部分 1:l ...

  3. linux tcp文件分包_在Linux下基于TCP协议的文件传输程序.

    [设计目的] 通过 Linux C 编程,设计一个基于 TCP/IP 的文件传输系统,实现网络文件的收发 [设计环境] Ubuntu 12.04 [设计方案] ( 1 )文件读写 任意文件都可以二进制 ...

  4. linux tcp文件分包_畅谈linux下TCP(下)

    三.TCP传输阶段 1 .TCP 包头 先认识一下TCP包头, 常规TCP包头为20个字节. 图一.png 可以通过TCP OPTION 扩展包头内容.TCP OPTION 是一个比较灵活的TLV结构 ...

  5. linux 删除文件命令_Linux系统常用的文件管理命令

    请关注本头条号,每天坚持更新原创干货技术文章. 如需学习视频,请在微信搜索公众号"智传网优"直接开始自助视频学习 1. 前言 本文主要讲解在Linux系统中,常用的文件管理工具有哪 ...

  6. linux mysql 文件恢复_linux下误删数据文件恢复

    linux下文件被删除可以用很多工具进行恢复,例如undelete(适合ext2,ext3).giis(不能恢复安装giis之前的文件).ext3grep(仅限ext3).R-linux(支持ext3 ...

  7. linux rm 文件找回_linux rm让你在删除的文件有地方找回 | DevOps

    一个不小心rm掉文件了吧?后悔莫及了吧! 把这段代码加入你的home目录的.bashrc或者.zshrc就可以了 工作原理:在你的home目录会创建一个.trash文件夹,里面会按照删除时间 年-月- ...

  8. linux windows文件 编码_Linux与Windows实现文件交互的几种方式

    对于很多人来说,都有自己的Windows与工作用的Linux,在项目进行过程中难免需要在这两个系统之间传输文件,以下列举几种本人知道并测试过的几种文件交互方式. 1.Ubuntu子系统 随着Windo ...

  9. linux压缩文件命令_Linux基础篇(二)--Linux常用命令

    Linux命令的执行需要依赖于Shell命令解释器.Shell实际上是在Linux系统中运行的一种特殊程序,Shell直译过来就是壳的意思,它位于操作系统内核之上,负责接受用户输入的命令并进行解释,将 ...

最新文章

  1. 2020年ACM团队新生第一次周赛题解
  2. Spring boot starter
  3. 史上最全的女人坐月子注意事項
  4. PyTorch 1.8 发布,支持 AMD,优化大规模训练
  5. 发布Library到JCenter
  6. 如何获取节假日的方法
  7. 进程之间究竟有哪些通信方式
  8. 一文说清:可逆与不可逆加密算法,对称与非对称加密算法-据说BCrypt比MD5要好?
  9. 【vue】Storage二次封装
  10. 英文歌曲:Yesterday Once More(昨日重现)
  11. notepad++插件
  12. Intellij Idea:禁忌,请勿手残
  13. 长三角城市群所有城市存贷款总额(2004-2019年)
  14. 【relativistic GAN :细节注入】
  15. 情人节,写给每一位单身朋友,愿早日脱单
  16. 20_Lambda表达式与Stream编程
  17. javaWeb基础六:JQuery—Ajax异步请求
  18. 10.4 中断控制方式
  19. SAP FICO 按月生成凭证编码解决方案
  20. 是时候推广秃头美学了

热门文章

  1. 字节跳动回应抖音上市;苹果公司:全球多个国家的 App 价格将上涨;GDB 10.1 发布|极客头条
  2. Linux Kernel 5.8 发布,华为内核代码贡献全球持续领先
  3. Deno 会取代 Node.js 吗?
  4. 深度学习技术干货免费听,AirPods2任性抽...520有场AI峰会不可错过!
  5. 干货!Python与MySQL数据库的交互实战
  6. 劳荣枝潜逃 23 年落网,多亏了它!
  7. 国内 UOS 统一操作系统曝光;联想宣布要 All in 5G​;Android Studio 新版发布 | 极客头条...
  8. 这个黑科技耳机方便又时尚,听歌也不怕坐过
  9. 社交界的 Linux,为何败给了 Facebook、Twitter?
  10. 雷军这么努力,为什么还是干不过 OV?