LINUX.ORG.RU

Не получается в sun rpc вернуть строку из многопоточнго сервера


0

0

Валится то сервер, то клиент с "segmentation fault".
Если убираю строки из параметров/возвр.значений, то все работает.
У Стивенса в "UNIX: взаимодействие процессов" в примерах тоже одни int-ы передаются и в статье http://solaris.opennet.ru/base/dev/rpc_example.txt.html тоже.
Где ошибка?
Где про это подробнее можно почитать?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
first.x :

struct proc1_in {
	string name<30>;
	int age;
};
struct proc1_out {
	string msg<30>;
	int prio;
};

struct proc2_in {
	string name<30>;
	int age;
};
struct proc2_out {
	string msg<30>;
	int prio;
};

program FIRST_PROG
{
	version FIRST_VERS
	{
		proc1_out FIRST_PROC1(proc1_in) = 1;
		proc2_out FIRST_PROC2(proc2_in) = 2;
	} = 1;
} = 0x31678860;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
server:
bool_t first_proc1_1_svc(proc1_in *inp, proc1_out *outp, struct svc_req *rqstp)
{
	fprintf(stderr, "%s: name:\"%s\" age:%d\n", __func__, inp->name, inp->age);
	outp->msg = "proc1";
	outp->prio = 1;
	return TRUE;
}

bool_t first_proc2_1_svc(proc2_in *inp, proc2_out *outp, struct svc_req *rqstp)
{
	fprintf(stderr, "%s: name:\"%s\" age:%d\n", __func__, inp->name, inp->age);
	outp->msg = "proc2";
	outp->prio = 2;
	return TRUE;
}

int first_prog_1_freeresult (SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result)
{
	xdr_free(xdr_result, result);
	return 1;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
client:
void client(char *host)
{
	CLIENT *clnt;
	enum clnt_stat retval_1;
	proc1_out result_1;
	proc1_in  first_proc1_1_arg;
	enum clnt_stat retval_2;
	proc2_out result_2;
	proc2_in  first_proc2_1_arg;

	first_proc1_1_arg.name = "Vasya";
	first_proc1_1_arg.age = 26;
	first_proc2_1_arg.name = "Kostya";
	first_proc2_1_arg.age = 14;
	clnt = clnt_create (host, FIRST_PROG, FIRST_VERS, "tcp");
	if (clnt == NULL) {
		clnt_pcreateerror (host);
		exit (1);
	}

	retval_1 = first_proc1_1(&first_proc1_1_arg, &result_1, clnt);
	if (retval_1 != RPC_SUCCESS) {
		clnt_perror (clnt, "call failed");
	}
	printf("%s %d\n", result_1.msg, result_1. prio);

	retval_2 = first_proc2_1(&first_proc2_1_arg, &result_2, clnt);
	if (retval_2 != RPC_SUCCESS) {
		clnt_perror (clnt, "call failed");
	}
	printf("%s %d\n", result_2.msg, result_2. prio);

	clnt_destroy (clnt);
}

Еще он у меня все равно получился не многопоточный

Я вставил sleep в процедуры сервера и обнаружил, процедуры вызываются последовательно.

Так как rpcgen не понимает опцию "-A" - автоматически создавать потоки по мере необходимости для обслуживания запросов клиентов.

В статье http://solaris.opennet.ru/base/dev/rpc_example.txt.html 
г-н Б. А. Державец изменяет файл *_svc.c 
Мне эта идея не нравится, т.к. мне придется его каждый раз править 
после того как поправлю .x файл.
Есть другое решение проблемы?

У меня RH 9.0, rpcgen не понимает опцию "--version".

vasirck
() автор топика

> Мне эта идея не нравится, т.к. мне придется его каждый раз править 
после того как поправлю .x файл.

Можно написать програмку, которая будет делать это сама и вставить ее
в Makefile. Не знаю пока как это быстрее сделать.
Но какие гарантии, что это не будет глючить?

vasirck
() автор топика
Ответ на: комментарий от vasirck

Наверно никто не пользуется sun rpc, т.к. никто не отвечает.
Может есть лучшая алтернатива на C/C++ для linux?

vasirck
() автор топика
Ответ на: комментарий от vasirck

Я со строками разобрался.
А с многопоточностью похоже никак.
Может еще кто-нить знает как callback-и делать?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
server:

bool_t first_proc1_1_svc(proc1_in *inp, proc1_out *outp, struct svc_req *rqstp)
{
	fprintf(stderr, "%s: name:\"%s\" age:%d\n", __func__, inp->name, inp->age);
	outp->msg = strdup("proc1");
	outp->prio = 1;
	sleep(3);
	return TRUE;
}

bool_t first_proc2_1_svc(proc2_in *inp, proc2_out *outp, struct svc_req *rqstp)
{
	fprintf(stderr, "%s: name:\"%s\" age:%d\n", __func__, inp->name, inp->age);
	outp->msg = strdup("proc2");
	outp->prio = 2;
	sleep(3);
	return TRUE;
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
client:
void client(char *host)
{
	CLIENT *clnt;
	enum clnt_stat retval_1;
	proc1_out result_1;
	proc1_in  first_proc1_1_arg;
	enum clnt_stat retval_2;
	proc2_out result_2;
	proc2_in  first_proc2_1_arg;
	char proc1_out_msg[30];
	char proc2_out_msg[30];
	result_1.msg = proc1_out_msg;
	result_2.msg = proc2_out_msg;

	first_proc1_1_arg.name = "Vasya";
	first_proc1_1_arg.age = 26;
	first_proc2_1_arg.name = "Kostya";
	first_proc2_1_arg.age = 14;
	clnt = clnt_create (host, FIRST_PROG, FIRST_VERS, "tcp");
	if (clnt == NULL) {
		clnt_pcreateerror (host);
		exit (1);
	}

	retval_1 = first_proc1_1(&first_proc1_1_arg, &result_1, clnt);
	if (retval_1 != RPC_SUCCESS) {
		clnt_perror (clnt, "call failed");
	}
	printf("%s %d\n", result_1.msg, result_1. prio);

	retval_2 = first_proc2_1(&first_proc2_1_arg, &result_2, clnt);
	if (retval_2 != RPC_SUCCESS) {
		clnt_perror (clnt, "call failed");
	}
	printf("%s %d\n", result_2.msg, result_2. prio);

	clnt_destroy (clnt);
}

vasirck
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.