server.c
来自「OTP是开放电信平台的简称」· C语言 代码 · 共 243 行
C
243 行
/* ``The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved via the world wide web at http://www.erlang.org/. * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' * * $Id$ */#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <string.h>#ifdef __WIN32__#include <winsock2.h>#include <direct.h>#include <windows.h>#include <winbase.h>#else /* not __WIN32__ */#include <errno.h> #include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h> #include <netdb.h>#endif#include "rmod_random__s.h"#include "ei_connect.h"/* Used functions */extern int gethostname(char *buf, int buflen);static int getport(int sockd);static int getlisten(int port);static int init(ei_cnode *ec, int *sd, int *portnr, int *epmd_fd);void terminate(int *fd, int *sd, int *epmd_fd);static void server_loop(ei_cnode *ec, int fd, int sd);/* change these, or even better, make command-line args to program... */#define COOKIE "flash"#define SERVER "babbis"#define NODENAMESZ 512#define HOSTNAMESZ 256#define INBUFSZ 1024#define OUTBUFSZ 1024int main(int argc, char **argv){ int sd; int portnr; int epmd_fd; ei_cnode ec; /* crate file descriptors */ if (init(&ec, &sd, &portnr, &epmd_fd) < 0) return -1; /* start server loop */ server_loop(&ec, sd, epmd_fd); return 0;}static void server_loop(ei_cnode *ec, int sd, int epmd_fd){ ErlConnect conn; erlang_msg msg; int status=1; CORBA_Environment *env; /* Create and init CORBA_Environment */ env = CORBA_Environment_alloc(INBUFSZ,OUTBUFSZ); while (status >= 0) { status = 1; if ((env->_fd = ei_accept(ec, sd, &conn)) < 0) { /* error */ fprintf(stderr,"Accept failed: %s\n",strerror(errno)); } else { /* connection */ fprintf(stderr,"Accepted connection from %s\n",conn.nodename); while (status >= 0) { /* write message to buffer */ status = ei_receive_encoded(env->_fd, &env->_inbuf, &env->_inbufsz, &msg, &env->_iin); switch(status) { case ERL_SEND: case ERL_REG_SEND : /* do transaction with fd */ rmod_random__switch(NULL,env); switch(env->_major) { case CORBA_NO_EXCEPTION: /* Success */ break; case CORBA_SYSTEM_EXCEPTION: /* System exception */ printf("Request failure, reason : %s\n",(char *) CORBA_exception_value(env)); CORBA_exception_free(env); break; default: /* Should not come here */ CORBA_exception_free(env); break; } /* send outdata */ if (env->_iout > 0) ei_send_encoded(env->_fd,&env->_caller,env->_outbuf,env->_iout); break; case ERL_TICK : break; default : /* < 0 */ printf("Connection terminated\n"); break; } } } status=0; /* restart */ } /* close file descriptors */ terminate(&env->_fd, &sd, &epmd_fd); /* Free env & buffers */ CORBA_free(env->_inbuf); CORBA_free(env->_outbuf); CORBA_free(env);} static int init(int *sd, int *portnr, int *epmd_fd){ char host[HOSTNAMESZ]; char servernode[NODENAMESZ]; struct hostent *h; /* get the host name */ if ((gethostname(host,HOSTNAMESZ))) fprintf(stderr,"can't find own hostname\n"); else { /* identify host */ if (!(h = erl_gethostbyname(host))) fprintf(stdout,"can't find own ip address\n"); else { /* get a listen port. 0 means let system choose port number */ *sd = getlisten(0); /* what port did we get? */ /* this call not necessary if we specified port in call to getlisten() */ *portnr = getport(*sd); /* make the nodename server@host */ sprintf(servernode,"%s@%s",SERVER,host); /* initiate */ /* cnode, host, alive, alive@host, addr, cookie, creation */ if (ei_connect_xinit(ec, host, SERVER, servernode, (Erl_IpAddr)(h->h_addr_list[0]), COOKIE, 0) == 0) { /* let epmd know we are here */ *epmd_fd = ei_publish(ec, *portnr); if (*epmd_fd >= 0) return 0; } } } return -1;}void terminate(int *fd, int *sd, int *epmd_fd) { close(*fd); /* remove info from epnd */ close(*epmd_fd); /* return socket */ close(*sd);}/* tells you what port you are using on given socket */static int getport(int sockd){ struct sockaddr_in addr; int namelen = sizeof(addr); int i; memset(&addr,0,sizeof(addr)); if ((i = getsockname(sockd,(struct sockaddr *)&addr,&namelen))<0) return i; return ntohs(addr.sin_port);}/* return a listen socket, bound to given port *//* specify port = 0 to let system assign port */static int getlisten(int port){ int sockd; struct sockaddr_in inaddr; int opt = 1; int i; /* get listen socket */ if ((sockd = socket(AF_INET,SOCK_STREAM,0)) < 0) return sockd; if ((i=setsockopt(sockd,SOL_SOCKET,SO_REUSEADDR,(void *)&opt,sizeof(opt)))<0) return i; /* bind to requested port */ memset(&inaddr,0,sizeof(inaddr)); inaddr.sin_family = AF_INET; inaddr.sin_addr.s_addr = htonl(INADDR_ANY); inaddr.sin_port = htons(port); if ((i = bind(sockd,(struct sockaddr*) &inaddr, sizeof(inaddr))) < 0) return i; listen(sockd,5); return sockd;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?