[UNIX网络编程] sun rpc实现的简单echo服务器

RPC的全称是Remote Procedure Call,它能够在本地以函数调用的形式来实现网络操作,让程序员集中关注于业务逻辑,不用关心底层的数据通信。

这里不会详细讲解RPC的原理,而是用一个简单的echo服务器的例子来说明如何使用RPC。

最早实现的RPC是sun rpc,现在它已经移植到了大多数操作系统。

使用RPC,程序员只需要关注客户与服务器之间数据传送的格式以及如何远程过程的定位,客户端如何调用本地函数以调用远程函数,服务器远程过程的实现。

1 客户端与服务器之间数据的交互

客户与服务器之间的数据传送是通过定义一个.x文件来实现的。在这个文件中,程序员可以定义客户端与服务器交互的数据格式,例如,我们的echo.x内容如下:

struct hello {
	char text[256];
};

struct hello_echo {
	char text_echo[256];
};

program ECHO_PROG {
	version ECHO_VERS {
		hello_echo ECHOPROC(hello) = 1;
	} = 1;
} = 0x31230000;

echo.x中定义了两个结构体,一个是struct hello,它是客户端向服务器发送的数据,一个是struct hello_echo,它服务器向客户端发送的内容。下面定义了一个program ECHO_PROG,这个结构体用于远程过程的定位,当客户端发送数据过来时,服务器需要确定调用哪个过程。

2 客户端调用远程过程

客户端通过一个CLIENT的句柄来调用远程过程:

        CLIENT *cl;
	hello in;
	hello_echo *outp;

	if(argc != 3) {
		fprintf(stderr, "usage: client <hostname> <integer_value>\n");
		exit(0);
	}

	cl = clnt_create(argv[1], ECHO_PROG, ECHO_VERS, "tcp");
	strncpy(in.text, argv[2], strlen(argv[2]));
	in.text[strlen(argv[2])] = 0;
	if((outp = echoproc_1(&in, cl)) == NULL) {
		fprintf(stderr, "%s\n", clnt_sperror(cl, argv[1]));
		exit(0);
	}
	printf("result: %s\n", outp->text_echo);

首先定义一个CLIENT的指针和两个用于发送数据和接收数据的参数,然后通过服务器的IP地址和远程过程的程序名以及版本号创建CLIENT,然后将命令行中的文本拷贝到发送参数hello in中,最后调用远程过程echoproc_1(),其中echoproc是在program ECHO_PROG中定义的函数名,但是所有字母都小写,1是该函数的版本号ECHO_VERS。

3 服务器远程过程的定义

服务器的主程序通过rpcgen自动生成,程序员只需要定义远程过程即可。

#include "echo.h"

hello_echo *echoproc_1_svc(hello *inp, struct svc_req *rqstp)
{
	static hello_echo out;
	strncpy(out.text_echo, inp->text, strlen(inp->text));
	out.text_echo[strlen(inp->text)] = 0;

	return (&out);
}

客户端调用的远程过程名是echoproc_1,而服务器真正执行的远程过程名则是echoproc_1_svc。

echoproc_1_svc()的参数和返回值已经确定了只要编写函数体即可。

这里的功能就是简单的回射,因此,执行一个strncpy就行,最后返回一个hello_echo的地址,由于是局部变量的地址,因此,要用静态局部变量。

4 程序的运行

首先对echo.x执行rpcgen得到头文件和服务器的主程序:

rpcgen -C echo.x

然后分别对客户端和服务器端进行编译:

gcc -o client client.c echo_clnt.c echo_xdr.c
gcc -o server echo_svc.c server_func.c echo_xdr.c

执行服务器:

./server

出现以下错误:

Cannot register service: RPC:  Authentication error; why = Client credential too weak

意思是认证错误,以root权限执行即可:

sudo ./server

然后执行客户端:

./client 127.0.0.1 abc

第三个参数发送什么,服务器就回送什么。

5 小结

RPC简化了开发网络应用的步骤,只要定义通信的数据和服务器的远程过程,就能够在客户端调用本地过程,RPC运行时库就能够自动调用远程过程。这对于开发大型的网络应用是十分方便的。

[UNIX网络编程] sun rpc实现的简单echo服务器,布布扣,bubuko.com

时间: 2024-10-10 09:31:02

[UNIX网络编程] sun rpc实现的简单echo服务器的相关文章

【UNIX网络编程(三)】TCP客户/服务器程序示例

上一节给出了TCP网络编程的函数,这一节使用那些基本函数编写一个完成的TCP客户/服务器程序示例. 该例子执行的步骤如下: 1.客户从标准输入读入一行文本,并写给服务器. 2.服务器从网络输入读入这行文本,并回射给客户. 3.客户从网络输入读入这行回射文本,并显示在标准输出上. 用图描述如下: 编写TCP回射服务器程序如下: #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <st

UNIX网络编程笔记(4)—TCP客户/服务器程序示例

TCP客户/服务器程序示例 这一章信息量开始大起来了,粗略来看它实现了简单的TCP客户/服务器程序,里面也有一些费解的细节. 1.概述 完整的TCP客户/服务器程序示例.这个简单的例子将执行如下步骤的一个回射服务器(这里的回射服务器就是服务简单的把客户端发送的消息返回给客户): 1)客户从标准输入读入一行文本,并写给服务器 2)服务器从网络输入读入这行文本,并回射给客户 3)客户从网络输入读入这行回射文本,并显示在标准输出上 这样实际上就构成了一个全双工的TCP连接. 本章就围绕了这个简单的TC

【LINUX/UNIX网络编程】之简单多线程服务器(多人群聊系统)

RT,Linux下使用c实现的多线程服务器.这个真是简单的不能再简单的了,有写的不好的地方,还希望大神轻拍.(>﹏<) 本学期Linux.unix网络编程的第四个作业. 先上实验要求: [实验目的] 1.熟练掌握线程的创建与终止方法: 2.熟练掌握线程间通信同步方法: 3.应用套接字函数完成多线程服务器,实现服务器与客户端的信息交互. [实验内容] 通过一个服务器实现最多5个客户之间的信息群发. 服务器显示客户的登录与退出: 客户连接后首先发送客户名称,之后发送群聊信息: 客户输入bye代表退

UNIX网络编程 卷2:进程间通信

这篇是计算机类的优质预售推荐>>>><UNIX网络编程 卷2:进程间通信(第2版)> UNIX和网络专家W. Richard Stevens的传世之作 编辑推荐 两卷本的<UNIX网络编程>是已故著名技术作家W. Richard Stevens的传世之作.卷2着重讨论怎样让应用程序与在其它机器上的应用程序进行对话. 良好的进程间通信(IPC)机制是提高UNIX程序性能的关键. 本书全面深入地解说了各种进程间通信形式,包括消息传递.同步.共享内存及远程过程调用

UNIX网络编程卷1 回射客户程序 TCP客户程序设计范式

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 下面我会介绍同一个使用 TCP 协议的客户端程序的几个不同版本,分别是停等版本.select 加阻塞式 I/O 版本. 非阻塞式 I/O 版本.fork 版本.线程化版本.它们都由同一个 main 函数调用来实现同一个功能,即回射程序客户端. 它从标准输入读入一行文本,写到服务器上,读取服务器对该行的回射,并把回射行写到标准输出上. 其中,非阻塞式 I/O 版本是所有版本中执行速度最快的,

【UNIX网络编程】进程间通信之管道

管道是最早的Unix进程间通信形式,它存在于全部的Unix实现中.关于管道,有例如以下几点须要知道: 1.它是半双工的,即数据仅仅能在一个方向上流动.虽然在某些Unix实现中管道能够是全双工的.但须要对系统进行某些设置.在Linux系统中,它是半双工的. 2.它没有名字.因此仅仅能在具有公共祖先的进程之间使用. 通经常使用在父子进程间.虽然这一点随着"有名管道FIFO"的增加得到改正了.但应该把它们看作是两种不同的进程间通信方式. 3.它由pipe函数创建,read和write函数訪问

将UNIX网络编程卷2的库函数合并到卷1的库函数中

源起 前面讲述了unix网路编程卷1库函数的配置.但是卷2还有一个配置,而且其中的关于进程间通信的函数在卷1中也没有. 我们使用两个库函数不免有些不方便,现在将卷2中的在卷1中没有的函数都合并到卷1的库函数中. 1.创建unix网络编程卷2——进程间通信configure.h配置文件    cd 目录    ./configure    之后创建了configure.h文件. 2.合并unix网路编程卷1和卷2的configure.h文件    将上面生成的configure.h的头文件的宏定义

[转载] 读《UNIX网络编程 卷1:套接字联网API》

原文: http://cstdlib.com/tech/2014/10/09/read-unix-network-programming-1/ 文章写的很清楚, 适合初学者 最近看了<UNIX网络编程 卷1:套接字联网API>, 英文名叫Unix Network Programming啦,后来上网查了查, 一般都叫UNP逼格会高一点, 就像APUE一样. 他们的作者都是W. Richard Stevens. 另外,他也是TCP/IP Illustrated的作者. 靠,看完作者简介,简直崇拜得

Unix网络编程 之 socket简介

概述 Socket的英文原意是"孔"或"插座",现在,作为Unix的进程通信机制,常常取"插座"这一意义.日常生活中常见的插座,有的是信号插座,有的是电源插座,有的可以接收信号或能量,有的可以发送信号或能量.举例来说,电话线与电话机之间需要一个插座(相当于两者之间的接口,这一部分装置物理上是存在的).对于网络编程,socket就相当于电话线与电话机之间的插座. 将电话系统与面向连接的Socket机制相比,两者之间有着惊人的相似的地方.以一个国家的