mirror of
https://github.com/haiwen/libsearpc.git
synced 2025-09-18 07:50:56 +00:00
1. Rearraged the source tree
2. modified the autotools scripts, "make distcheck" is ok now
This commit is contained in:
12
demo/Makefile.am
Normal file
12
demo/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
AM_CFLAGS = @GLIB2_CFLAGS@ @GOBJECT_CFLAGS@ @JSON_GLIB_CFLAGS@ -I${top_builddir}/lib -I${top_srcdir}/lib
|
||||
|
||||
noinst_PROGRAMS = searpc-demo-server searpc-demo-client
|
||||
|
||||
searpc_demo_server_SOURCES = searpc-demo-server.c searpc-demo-packet.h
|
||||
|
||||
searpc_demo_server_LDADD = ${top_builddir}/lib/libsearpc.la
|
||||
|
||||
searpc_demo_client_SOURCES = searpc-demo-client.c searpc-demo-packet.h
|
||||
|
||||
searpc_demo_client_LDADD = ${top_builddir}/lib/libsearpc.la
|
||||
|
104
demo/searpc-demo-client.c
Normal file
104
demo/searpc-demo-client.c
Normal file
@@ -0,0 +1,104 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "searpc-client.h"
|
||||
#include "searpc-demo-packet.h"
|
||||
|
||||
#define BUFLEN 256
|
||||
#define MAGIC_STRING "ABCD"
|
||||
|
||||
/* define the client-side function */
|
||||
SEARPC_CLIENT_DEFUN_INT__STRING(searpc_demo_int__string);
|
||||
|
||||
static char *transport_callback(void *arg, const char *fcall_str,
|
||||
size_t fcall_len, size_t *ret_len)
|
||||
{
|
||||
int fd, ret;
|
||||
char buf[BUFLEN];
|
||||
packet *pac, *pac_ret;
|
||||
|
||||
fd = (int) arg;
|
||||
pac = (packet *)buf;
|
||||
|
||||
/* construct the packet */
|
||||
pac->length = htons((uint16_t)fcall_len);
|
||||
strncpy(pac->data, fcall_str, fcall_len);
|
||||
|
||||
/* send the packet */
|
||||
if ( writen (fd, buf, PACKET_HEADER_LENGTH + fcall_len) == -1) {
|
||||
fprintf (stderr, "write failed: %s\n", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* read the returned packet */
|
||||
pac_ret = read_packet(fd, buf);
|
||||
if (pac_ret == NULL) {
|
||||
fprintf(stderr, "read packet failed: %s\n", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
*ret_len = ntohs(pac_ret->length);
|
||||
|
||||
return strndup(pac_ret->data, *ret_len);
|
||||
}
|
||||
|
||||
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int sockfd, ret;
|
||||
char *ret_str;
|
||||
struct sockaddr_in servaddr;
|
||||
SearpcClient *rpc_client;
|
||||
GError *error = NULL;
|
||||
|
||||
g_type_init();
|
||||
|
||||
ret = sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "socket failed: %s\n", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int on = 1;
|
||||
if (setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
|
||||
fprintf (stderr, "setsockopt of SO_REUSEADDR error: %s\n", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
memset(&servaddr, 0, sizeof(servaddr));
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_port = htons(12345);
|
||||
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
|
||||
|
||||
ret = connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "connect failed: %s\n", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* create an rpc_client and supply the transport function. */
|
||||
rpc_client = searpc_client_new();
|
||||
rpc_client->transport = transport_callback;
|
||||
rpc_client->arg = (void *)sockfd;
|
||||
|
||||
/* call the client-side funcion */
|
||||
ret = searpc_demo_int__string(rpc_client, "hello searpc", &error);
|
||||
if (error != NULL) {
|
||||
fprintf(stderr, "error: %s\n", error->message);
|
||||
exit(-1);
|
||||
} else
|
||||
printf("%d\n", ret);
|
||||
|
||||
close(sockfd);
|
||||
|
||||
return 0;
|
||||
}
|
87
demo/searpc-demo-packet.h
Normal file
87
demo/searpc-demo-packet.h
Normal file
@@ -0,0 +1,87 @@
|
||||
|
||||
#ifndef _PACKET_H
|
||||
#define _PACKET_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
typedef struct packet {
|
||||
uint16_t length;
|
||||
char data[0];
|
||||
} packet;
|
||||
|
||||
# define PACKET_HEADER_LENGTH sizeof(packet)
|
||||
|
||||
static ssize_t /* Write "n" bytes to a descriptor. */
|
||||
writen(int fd, const void *vptr, size_t n)
|
||||
{
|
||||
size_t nleft;
|
||||
ssize_t nwritten;
|
||||
const char *ptr;
|
||||
|
||||
ptr = vptr;
|
||||
nleft = n;
|
||||
while (nleft > 0) {
|
||||
if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
|
||||
if (nwritten < 0 && errno == EINTR)
|
||||
nwritten = 0; /* and call write() again */
|
||||
else
|
||||
return(-1); /* error */
|
||||
}
|
||||
|
||||
nleft -= nwritten;
|
||||
ptr += nwritten;
|
||||
}
|
||||
return(n);
|
||||
}
|
||||
|
||||
static ssize_t /* Read "n" bytes from a descriptor. */
|
||||
readn(int fd, char *buf, size_t n)
|
||||
{
|
||||
size_t nleft;
|
||||
ssize_t nread;
|
||||
|
||||
nleft = n;
|
||||
while (nleft > 0) {
|
||||
if ( (nread = read(fd, buf, nleft)) < 0) {
|
||||
if (errno == EINTR)
|
||||
nread = 0; /* and call read() again */
|
||||
else
|
||||
return(-1);
|
||||
} else if (nread == 0)
|
||||
break; /* EOF */
|
||||
|
||||
nleft -= nread;
|
||||
buf += nread;
|
||||
}
|
||||
|
||||
return(n - nleft); /* return >= 0 */
|
||||
}
|
||||
|
||||
|
||||
/* read a packet into a buffer, and return the pacet pointer */
|
||||
packet *
|
||||
read_packet(int sockfd, char *buf)
|
||||
{
|
||||
packet *pac;
|
||||
int len;
|
||||
/* read the length part */
|
||||
if (readn (sockfd, buf, PACKET_HEADER_LENGTH) != PACKET_HEADER_LENGTH) {
|
||||
fprintf(stderr, "read header error: %s\n", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
pac = (packet *)buf;
|
||||
len = ntohs(pac->length);
|
||||
/* read the data */
|
||||
if (len <= 0)
|
||||
return NULL;
|
||||
else if (readn (sockfd, buf + PACKET_HEADER_LENGTH, len) != len)
|
||||
return NULL;
|
||||
|
||||
return pac;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
112
demo/searpc-demo-server.c
Normal file
112
demo/searpc-demo-server.c
Normal file
@@ -0,0 +1,112 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "searpc-server.h"
|
||||
#include "searpc-demo-packet.h"
|
||||
#define BUFLEN 256
|
||||
|
||||
static int
|
||||
searpc_demo_int__string(const char *str)
|
||||
{
|
||||
if (str == NULL)
|
||||
return -1;
|
||||
else
|
||||
return strlen(str);
|
||||
}
|
||||
|
||||
static void
|
||||
start_rpc_service(void)
|
||||
{
|
||||
searpc_server_init();
|
||||
|
||||
searpc_server_register_function(searpc_demo_int__string,
|
||||
"searpc_demo_int__string",
|
||||
searpc_signature_int__string());
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int listenfd, connfd;
|
||||
int ret;
|
||||
struct sockaddr_in client_addr, server_addr;
|
||||
socklen_t clilen;
|
||||
char buf[BUFLEN];
|
||||
packet *pac, *pac_ret;
|
||||
g_type_init();
|
||||
|
||||
start_rpc_service();
|
||||
|
||||
listenfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (listenfd < 0) {
|
||||
fprintf(stderr, "socket failed: %s\n", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int on = 1;
|
||||
if (setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
|
||||
fprintf (stderr, "setsockopt of SO_REUSEADDR error: %s\n", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
server_addr.sin_port = htons(12345);
|
||||
|
||||
ret = bind(listenfd, (struct sockaddr *)&server_addr,
|
||||
sizeof(server_addr));
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "bind failed: %s\n", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
ret = listen(listenfd, 5);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "listen failed: %s\n", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
clilen = sizeof(client_addr);
|
||||
connfd = accept(listenfd, (struct sockaddr *)&client_addr, &clilen);
|
||||
if (connfd < 0) {
|
||||
fprintf(stderr, "accept failed: %s\n", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* read the header packet */
|
||||
pac = read_packet(connfd, buf);
|
||||
if (pac == NULL) {
|
||||
fprintf(stderr, "read packet failed: %s\n", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
gsize ret_len;
|
||||
int fcall_len = ntohs(pac->length);
|
||||
/* Execute the RPC function */
|
||||
char *res = searpc_server_call_function (pac->data, fcall_len, &ret_len);
|
||||
|
||||
pac_ret = (packet *)buf;
|
||||
pac_ret->length = htons((uint16_t)ret_len);
|
||||
strncpy(pac_ret->data, res, ret_len);
|
||||
|
||||
/* send the ret packet */
|
||||
if (writen (connfd, buf, PACKET_HEADER_LENGTH + ret_len) == -1) {
|
||||
fprintf (stderr, "write packet failed: %s\n", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user