libsent/src/net/server-client.c

Go to the documentation of this file.
00001 
00018 /*
00019  * Copyright (c) 1991-2007 Kawahara Lab., Kyoto University
00020  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00021  * Copyright (c) 2005-2007 Julius project team, Nagoya Institute of Technology
00022  * All rights reserved
00023  */
00024 
00025 #include <sent/stddefs.h>
00026 #include <sent/tcpip.h>
00027 
00028 #ifdef WINSOCK
00029 boolean winsock_initialized = FALSE; 
00030 #endif
00031 
00040 int
00041 ready_as_server(int port_num)
00042 {
00043   struct sockaddr_in sin;
00044   int sd;
00045   int optval;
00046   int optlen;
00047 
00048 #ifdef WINSOCK
00049   /* init winsock */
00050   if (!winsock_initialized) {
00051     WSADATA data;
00052     WSAStartup(0x1010, &data);
00053     winsock_initialized = TRUE;
00054   }
00055 #endif
00056 
00057   /* create socket */
00058 #ifdef WINSOCK
00059   if((sd = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET){
00060     jlog("Error: server-client: socket() error\n");
00061     jlog("Error: server-client: error code = %d\n", WSAGetLastError());
00062     switch(WSAGetLastError()) {
00063     case WSANOTINITIALISED: jlog("Error: server-client: reason: A successful WSAStartup must occur before using this function.\n"); break;
00064     case WSAENETDOWN: jlog("Error: server-client: reason: The network subsystem or the associated service provider has failed.\n"); break;
00065     case WSAEAFNOSUPPORT: jlog("Error: server-client: reason: The specified address family is not supported. \n"); break;
00066      case WSAEINPROGRESS: jlog("Error: server-client: reason: A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function. \n"); break;
00067     case WSAEMFILE: jlog("Error: server-client: reason: No more socket descriptors are available. \n"); break;
00068     case WSAENOBUFS: jlog("Error: server-client: reason: No buffer space is available. The socket cannot be created. \n"); break;
00069     case WSAEPROTONOSUPPORT: jlog("Error: server-client: reason: The specified protocol is not supported. \n"); break;
00070     case WSAEPROTOTYPE: jlog("Error: server-client: reason: The specified protocol is the wrong type for this socket. \n"); break;
00071     case WSAESOCKTNOSUPPORT: jlog("Error: server-client: reason: The specified socket type is not supported in this address family. \n"); break;
00072     }
00073     return -1;
00074   }
00075 #else  /* ~WINSOCK */
00076   if((sd = socket(PF_INET, SOCK_STREAM, 0)) < 0){
00077     jlog("Error: server-client: socket() error\n");
00078     return -1;
00079   }
00080 #endif /* ~WINSOCK */
00081 
00082   /* set socket to allow reuse of local address at bind() */
00083   /* this option prevent from "error: Address already in use" */
00084   optval = 1;
00085   optlen = sizeof(int);
00086   if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, optlen) != 0) {
00087     jlog("Error: server-client: socketopt() error\n");
00088     return -2;
00089   }
00090 
00091   /* assign name(address) to socket */
00092   memset((char *)&sin, 0, sizeof(sin));
00093   sin.sin_family = AF_INET;
00094   sin.sin_port = htons((unsigned short)port_num);
00095   if(bind(sd, (struct sockaddr *)&sin, sizeof(sin)) < 0){
00096     jlog("Error: server-client: bind() error\n");
00097     return -2;
00098   }
00099   /* begin to listen */
00100   if (listen(sd, 5) < 0) {
00101     jlog("Error: server-client: listen() error\n");
00102     return -3;
00103   }
00104 
00105   jlog("Stat: server-client: socket ready as server\n");
00106 
00107   return(sd);
00108 }
00109 
00119 int
00120 accept_from(int sd)
00121 {
00122   static struct sockaddr_in from;
00123 #ifdef HAVE_SOCKLEN_T
00124   static socklen_t nbyte;
00125 #else  
00126   static int nbyte;
00127 #endif /* HAVE_SOCKLEN_T */
00128   int asd;
00129 
00130   nbyte = sizeof(struct sockaddr_in);
00131   asd = accept(sd, (struct sockaddr *)&from, &nbyte);
00132   if (asd < 0) {              /* error */
00133     jlog("Error: server-client: accept() error\n");
00134     jlog("Error: server-client: failed to accept connection\n");
00135 #ifdef WINSOCK
00136     switch(WSAGetLastError()) {
00137     case WSANOTINITIALISED: jlog("Error: server-client: reason: A successful WSAStartup must occur before using this FUNCTION. \n"); break;
00138     case WSAENETDOWN: jlog("Error: server-client: reason:  The network subsystem has failed. \n"); break;
00139     case WSAEFAULT: jlog("Error: server-client: reason:  The addrlen parameter is too small or addr is not a valid part of the user address space. \n"); break;
00140     case WSAEINTR: jlog("Error: server-client: reason:  A blocking Windows Sockets 1.1 call was canceled through WSACancelBlockingCall. \n"); break;
00141     case WSAEINPROGRESS: jlog("Error: server-client: reason:  A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function. \n"); break;
00142     case WSAEINVAL: jlog("Error: server-client: reason:  The listen function was not invoked prior to accept. \n"); break;
00143     case WSAEMFILE: jlog("Error: server-client: reason:  The queue is nonempty upon entry to accept and there are no descriptors available. \n"); break;
00144     case WSAENOBUFS: jlog("Error: server-client: reason:  No buffer space is available. \n"); break;
00145     case WSAENOTSOCK: jlog("Error: server-client: reason:  The descriptor is not a socket. \n"); break;
00146     case WSAEOPNOTSUPP: jlog("Error: server-client: reason:  The referenced socket is not a type that supports connection-oriented service. \n"); break;
00147     case WSAEWOULDBLOCK: jlog("Error: server-client: reason:  The socket is marked as nonblocking and no connections are present to be accepted. \n"); break;
00148     }
00149 #endif
00150     return -1;
00151   }
00152   jlog("Stat: server-client: connect from %s\n", inet_ntoa(from.sin_addr));
00153   return asd;
00154 }
00155   
00164 int
00165 make_connection(char *hostname, int port_num)
00166 {
00167   static struct hostent *hp;
00168   static struct sockaddr_in     sin;
00169   int sd;
00170   int trynum;
00171 
00172 #ifdef WINSOCK
00173   /* init winsock */
00174   if (!winsock_initialized) {
00175     WSADATA data;
00176     WSAStartup(0x1010, &data);
00177     winsock_initialized = TRUE;
00178   }
00179 #endif
00180 
00181   /* host existence check */
00182   if ((hp  = gethostbyname(hostname)) == NULL) {
00183     jlog("Error: server-client: target host not found: %s\n", hostname);
00184     return -3;
00185   }
00186 
00187   /* create socket */
00188 #ifdef WINSOCK
00189   if((sd = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET){
00190     jlog("Error: server-client: failed to create socket\n") ;
00191     jlog("Error: server-client: Error code: %d\n", WSAGetLastError());
00192     switch(WSAGetLastError()) {
00193     case WSANOTINITIALISED: jlog("Error: server-client: reason: A successful WSAStartup must occur before using this function.\n"); break;
00194     case WSAENETDOWN: jlog("Error: server-client: reason: The network subsystem or the associated service provider has failed.\n"); break;
00195     case WSAEAFNOSUPPORT: jlog("Error: server-client: reason: The specified address family is not supported. \n"); break;
00196     case WSAEINPROGRESS: jlog("Error: server-client: reason: A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function. \n"); break;
00197     case WSAEMFILE: jlog("Error: server-client: reason: No more socket descriptors are available. \n"); break;
00198     case WSAENOBUFS: jlog("Error: server-client: reason: No buffer space is available. The socket cannot be created. \n"); break;
00199     case WSAEPROTONOSUPPORT: jlog("Error: server-client: reason: The specified protocol is not supported. \n"); break;
00200     case WSAEPROTOTYPE: jlog("Error: server-client: reason: The specified protocol is the wrong type for this socket. \n"); break;
00201     case WSAESOCKTNOSUPPORT: jlog("Error: server-client: reason: The specified socket type is not supported in this address family. \n"); break;
00202     }
00203     return -1;
00204   }
00205 #else  /* ~WINSOCK */
00206   if((sd = socket(PF_INET, SOCK_STREAM, 0)) < 0){
00207     jlog("Error: server-client: failed to create socket\n") ;
00208     return -1;
00209   }
00210 #endif /* ~WINSOCK */
00211 
00212   /* try to connect */
00213   for (trynum = 0; trynum < CONNECTION_RETRY_TIMES; trynum++) {
00214     memset((char *)&sin, 0, sizeof(sin));
00215     memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
00216     sin.sin_family = hp->h_addrtype;
00217     sin.sin_port = htons((unsigned short)port_num);
00218     if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) >= 0) {
00219       /* success */
00220       break;
00221     } else {
00222       /* failure */
00223       jlog("Stat: server-client: conection failed\n") ;
00224       /* retry */
00225       jlog("Stat: server-client: retry after %d second...\n", CONNECTION_RETRY_INTERVAL);
00226       sleep(CONNECTION_RETRY_INTERVAL);
00227     }
00228   }
00229   if (trynum == CONNECTION_RETRY_TIMES) {
00230     /* finally failed */
00231     jlog("Error: server-client: failed to connect to %s:%d\n", hostname, port_num);
00232     return -2;
00233   }
00234 
00235   return sd;
00236 }
00237 
00238 #ifndef WINSOCK
00239 
00247 int
00248 make_connection_unix(char *address)
00249 {
00250   struct sockaddr_un    ps;
00251   int len;
00252   int sd;
00253 
00254   ps.sun_family = PF_UNIX;
00255   strcpy(ps.sun_path, address);
00256   len = sizeof(ps.sun_family) + strlen(ps.sun_path);
00257 
00258   if((sd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0){
00259     jlog("Error: server-client: failed to create socket\n");
00260     return -1;
00261   }
00262   while(connect(sd, (struct sockaddr *)&ps, len) < 0){
00263     jlog("Error: server-client: failed to conect to %s\n", address);
00264     /* retry */
00265     jlog("Error: server-client: retry after %d sec...\n",CONNECTION_RETRY_INTERVAL);
00266     sleep(CONNECTION_RETRY_INTERVAL);
00267   }
00268 
00269   jlog("Stat: server-client: connected to unix socket %s\n", address);
00270   
00271   return sd;
00272 }
00273 #endif /* ~WINSOCK */
00274 
00282 int
00283 close_socket(int sd)
00284 {
00285   int ret;
00286 #ifdef WINSOCK
00287   ret = closesocket(sd);
00288 #else
00289   ret = close(sd);
00290 #endif
00291   return(ret);
00292 }
00293   
00298 void
00299 cleanup_socket()
00300 {
00301 #ifdef WINSOCK
00302   if (winsock_initialized) {
00303     WSACleanup();
00304   }
00305 #endif
00306 }

Generated on Tue Dec 18 15:59:55 2007 for Julius by  doxygen 1.5.4