本程序基于进程间的管道通信实现了简单的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
#include
#include
#include
#include
#include
#include
#include
#include
#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 \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 \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