本程序基于进程间的管道通信实现了简单的tftp的功能。
功能包括
put:向服务器上传文件
get:从服务器下载文件
list:列出服务器文件列表
help、?:查看支持的命令
quit:退出登录
先运行服务器端,在某个目录下创建一个公用的管道;
然后运行客户端,创建自己的管道,并通过服务器通用的管道与服务器端完成握手。
1.共用的头文件
buf.h
#ifndef _BUF_ #define _BUF_ #define SIZE 1024 typedef enum type{//数据类型 LOGIN = 100, PUT, GET, QUIT, LIST, END, DATA, YES, NO }BUF_TYPE; typedef struct buf{//数据帧封装 BUF_TYPE type;//数据类型 int len;//数据长度 char data[SIZE];//数据内容 }BUF; #define BUF_SIZE sizeof(BUF) void pack_buf(BUF *buf, BUF_TYPE, const void *data, int len); int send_buf(int fifo_fd, void *buf, int size); #endifbuf.c
#include "buf.h" #include "common.h" void pack_buf(BUF *buf, BUF_TYPE type, const void *data, int len) { bzero(buf, BUF_SIZE); buf->type = type; buf->len = len; memcpy(buf->data, data, len); } int send_buf(int fifo_fd, void *buf, int size) { int n; if( 0 == (n = write(fifo_fd, buf, size) )) { err_sys("send packet"); } return n; }common.h
#ifndef _COM_ #define _COM_ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <error.h> #define err_sys(err_str) {perror(err_str); exit(-1);} #endif
2.客户端程序
client.c
#include "common.h" #include "buf.h" #include "client_do.h" int main(int argc, char **argv) { if(3 != argc) { printf("Usage: %s <server_fifo> <my_fifo>\n", argv[0]); exit(-1); } int server_fifo_fd = open(argv[1], O_WRONLY); if(-1 == server_fifo_fd) { err_sys("open server fifo"); } int my_fifo_fd = open(argv[2], O_RDWR); if(-1 == my_fifo_fd) { if(ENOENT == errno) { if(-1 == mkfifo(argv[2], 0666)) { err_sys("make my fifo"); } my_fifo_fd = open(argv[2], O_RDONLY); if(-1 == my_fifo_fd) { err_sys("open myfifo 2"); } } else { err_sys("open myfifo"); } } if(NO == do_hand(argv[2], server_fifo_fd, my_fifo_fd)) //告诉服务器我的管道名(握手) { printf("hand shake failed!\n"); return; } char cmd_buf[100]; while(1) { bzero(cmd_buf, 100); printf("mytftp> ");fflush(stdout); gets(cmd_buf); if(0 == strncmp("put", cmd_buf, 3) ) //用户想上传 { do_put(server_fifo_fd, cmd_buf+4); } else if(0 == strncmp("get", cmd_buf, 3) )//用户想下载 { do_get(server_fifo_fd, my_fifo_fd, cmd_buf+4); } else if(0 == strncmp("list", cmd_buf, 4) )//用户想得到服务器文件列表 { do_list(server_fifo_fd, my_fifo_fd); } else if(0 == strncmp("help", cmd_buf, 4) || *cmd_buf == ‘?‘ )//用户想知道此软件支持哪些命令 { do_help(); } else if(0 == strncmp("quit", cmd_buf, 4) )//不想用了 { do_quit(server_fifo_fd, my_fifo_fd); } else//瞎按 { printf("cmd err!, try again ! \n"); } } }
client_do.h
#ifndef _CLIENT_DO #define _CLIENT_DO int do_hand(const char *myfifo_name,int server_fifo_fd, int my_fifo_fd); void do_put(int server_fifo_fd, const char *myfifo_name); void do_get(int server_fifo_fd, int my_fifo_fd, const char *file_name); void do_list(int server_fifo_fd, int my_fifo_fd); void do_help(void); void do_quit(int server_fifo_fd, int client_fifo_fd); #endifclient_do.c
#include "client_do.h" #include "common.h" #include "buf.h" int do_hand(const char *myfifo_name,int server_fifo_fd, int my_fifo_fd) { BUF buf; pack_buf(&buf, LOGIN, myfifo_name, strlen(myfifo_name)); send_buf(server_fifo_fd, &buf, BUF_SIZE); read(my_fifo_fd, &buf, BUF_SIZE); return buf.type; } void do_put(int server_fifo_fd, const char *file_name) { int file_fd = open(file_name, O_RDONLY); if(-1 == file_fd) { printf("no such file !\n"); return; } BUF buf; pack_buf(&buf, PUT, file_name, strlen(file_name)); send_buf(server_fifo_fd, &buf, BUF_SIZE); buf.type = DATA; while(1) { buf.len = read(file_fd, buf.data, SIZE); if(0 == buf.len) { buf.type = END; send_buf(server_fifo_fd, &buf, BUF_SIZE); break; } send_buf(server_fifo_fd, &buf, BUF_SIZE); } } void do_get(int server_fifo_fd, int my_fifo_fd, const char *file_name) { BUF buf; pack_buf(&buf, GET, file_name, strlen(file_name)); send_buf(server_fifo_fd, &buf, BUF_SIZE); read(my_fifo_fd, &buf, BUF_SIZE); if(NO == buf.type) { printf("no such file on server! \n"); return; } int file_fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666); if(-1 == file_fd) { printf("cann‘t open file! \n "); return; } while(1) { printf("%d\n", read(my_fifo_fd, &buf, BUF_SIZE)); printf("======%d=========\n", buf.len); if(END == buf.type) { close(file_fd); break; } write(file_fd, buf.data, buf.len); } } void do_list(int server_fifo_fd, int my_fifo_fd) { BUF buf; pack_buf(&buf, LIST, NULL, 0); send_buf(server_fifo_fd, &buf, BUF_SIZE); while(1) { read(my_fifo_fd, &buf, BUF_SIZE); if(END == buf.type) break; printf("%s\t", buf.data); } printf("\n"); } void do_help(void) { printf("\n/********************************************/\n"); printf("/*********get********************************/\n"); printf("/*********put********************************/\n"); printf("/*********list*******************************/\n"); printf("/*********help*******************************/\n"); printf("/*********quit*******************************/\n"); printf("/********************************************/\n\n"); } void do_quit(int server_fifo_fd, int client_fifo_fd) { exit(0); }3.服务器端程序
server_do.h
#ifndef _SERVER_DO #define _SERVER_DO void do_put(const char *file_name, int server_fifo_fd); void do_get(const char *file_name, int client_fifo_fd); void do_list(int client_fifo_fd); void do_quit(void); #endifserver_do.c
#include "server_d.h" #include "buf.h" #include "common.h" void do_put(const char *file_name, int server_fifo_fd) { int file_fd = open(file_name, O_CREAT|O_WRONLY|O_TRUNC, 0666); if(-1 == file_fd) err_sys("open file"); BUF buf; while(1) { bzero(&buf, BUF_SIZE); read(server_fifo_fd, &buf, BUF_SIZE); if(END == buf.type) { close(file_fd); break; } write(file_fd, buf.data, buf.len); } } void do_get(const char *file_name, int client_fifo_fd) { BUF buf; int file_fd = open(file_name, O_RDONLY); if(-1 == file_fd) { if(ENOENT == errno) { pack_buf(&buf, NO, NULL, 0); send_buf(client_fifo_fd, &buf, BUF_SIZE); return; } } buf.type = DATA; while(1) { bzero(&buf, BUF_SIZE); buf.len = read(file_fd, buf.data, SIZE); printf("aaaaaaa%daaaaaaa\n", buf.len); if(0 == buf.len) { buf.type = END; send_buf(client_fifo_fd, &buf, BUF_SIZE); break; } send_buf(client_fifo_fd, &buf, BUF_SIZE); } } void do_list(int client_fifo_fd) { DIR *dp = opendir("."); if(NULL == dp) err_sys("opendir"); BUF buf = {DATA}; struct dirent *p; while(1) { if(NULL == (p = readdir(dp))) { buf.type = END; send_buf(client_fifo_fd, &buf, BUF_SIZE); break; } strcpy(buf.data, p->d_name); send_buf(client_fifo_fd, &buf, BUF_SIZE); } } void do_quit(void) { }server.c
#include "common.h" #include "buf.h" #include "server_d.h" int main(int argc, char **argv) { if(2 != argc) { printf("Usage: %s <server_fifo>\n", argv[0]); exit(-1); } int server_fifo_fd = open(argv[1], O_RDONLY); if(-1 == server_fifo_fd) err_sys("open server fifo"); int client_fifo_fd; BUF buf; read(server_fifo_fd, &buf, BUF_SIZE); if(LOGIN == buf.type) { client_fifo_fd = open(buf.data, O_WRONLY); if(-1 == client_fifo_fd) err_sys("open client fifo"); pack_buf(&buf, YES, NULL, 0); send_buf(client_fifo_fd, &buf, BUF_SIZE); } while(1) { bzero(&buf, BUF_SIZE); read(server_fifo_fd, &buf, BUF_SIZE); switch(buf.type) { case PUT: do_put(buf.data, server_fifo_fd);break; case GET: do_get(buf.data, client_fifo_fd);break; case LIST: do_list(client_fifo_fd);break; case QUIT: do_quit();break; } } }
原文:http://blog.csdn.net/it_liuwei/article/details/19566201