首页 > 其他 > 详细

linux进程间通过管道通信实现简单的tftp

时间:2014-02-21 11:04:18      阅读:622      评论:0      收藏:0      [点我收藏+]

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

#endif
buf.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);

#endif
client_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);

#endif
server_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;
		}
	}
}


linux进程间通过管道通信实现简单的tftp

原文:http://blog.csdn.net/it_liuwei/article/details/19566201

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!