00001
00017
00018
00019
00020
00021
00022
00023
00024 #include <sent/stddefs.h>
00025 #include <sent/tcpip.h>
00026
00027 #ifdef WINSOCK
00028 boolean winsock_initialized = FALSE;
00029 #endif
00030
00039 int
00040 ready_as_server(int port_num)
00041 {
00042 struct sockaddr_in sin;
00043 int sd;
00044 int optval;
00045 int optlen;
00046
00047 #ifdef WINSOCK
00048
00049 if (!winsock_initialized) {
00050 WSADATA data;
00051 WSAStartup(0x1010, &data);
00052 winsock_initialized = TRUE;
00053 }
00054 #endif
00055
00056
00057 #ifdef WINSOCK
00058 if((sd = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET){
00059 perror("ready_as_server: socket() error") ;
00060 printf("Error code: %d\n", WSAGetLastError());
00061 switch(WSAGetLastError()) {
00062 case WSANOTINITIALISED: printf("A successful WSAStartup must occur before using this function.\n"); break;
00063 case WSAENETDOWN: printf("The network subsystem or the associated service provider has failed.\n"); break;
00064 case WSAEAFNOSUPPORT: printf("The specified address family is not supported. \n"); break;
00065 case WSAEINPROGRESS: printf("A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function. \n"); break;
00066 case WSAEMFILE: printf("No more socket descriptors are available. \n"); break;
00067 case WSAENOBUFS: printf("No buffer space is available. The socket cannot be created. \n"); break;
00068 case WSAEPROTONOSUPPORT: printf("The specified protocol is not supported. \n"); break;
00069 case WSAEPROTOTYPE: printf("The specified protocol is the wrong type for this socket. \n"); break;
00070 case WSAESOCKTNOSUPPORT: printf("The specified socket type is not supported in this address family. \n"); break;
00071 }
00072 return -1;
00073 }
00074 #else
00075 if((sd = socket(PF_INET, SOCK_STREAM, 0)) < 0){
00076 perror("ready_as_server: socket() error") ;
00077 return -1;
00078 }
00079 #endif
00080
00081
00082
00083 optval = 1;
00084 optlen = sizeof(int);
00085 if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, optlen) != 0) {
00086 perror("ready_as_server: setsockopt() error");
00087 return -2;
00088 }
00089
00090
00091 memset((char *)&sin, 0, sizeof(sin));
00092 sin.sin_family = AF_INET;
00093 sin.sin_port = htons((unsigned short)port_num);
00094 if(bind(sd, (struct sockaddr *)&sin, sizeof(sin)) < 0){
00095 perror("ready_as_server: bind() error") ;
00096 return -2;
00097 }
00098
00099 if (listen(sd, 5) < 0) {
00100 perror("ready_as_server: listen() error");
00101 return -3;
00102 }
00103 return(sd);
00104 }
00105
00115 int
00116 accept_from(int sd)
00117 {
00118 static struct sockaddr_in from;
00119 #ifdef HAVE_SOCKLEN_T
00120 static socklen_t nbyte;
00121 #else
00122 static int nbyte;
00123 #endif
00124 int asd;
00125
00126 nbyte = sizeof(struct sockaddr_in);
00127 asd = accept(sd, (struct sockaddr *)&from, &nbyte);
00128 if (asd < 0) {
00129 #ifdef WINSOCK
00130 switch(WSAGetLastError()) {
00131 case WSANOTINITIALISED: printf("A successful WSAStartup must occur before using this FUNCTION. \n"); break;
00132 case WSAENETDOWN: printf(" The network subsystem has failed. \n"); break;
00133 case WSAEFAULT: printf(" The addrlen parameter is too small or addr is not a valid part of the user address space. \n"); break;
00134 case WSAEINTR: printf(" A blocking Windows Sockets 1.1 call was canceled through WSACancelBlockingCall. \n"); break;
00135 case WSAEINPROGRESS: printf(" A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function. \n"); break;
00136 case WSAEINVAL: printf(" The listen function was not invoked prior to accept. \n"); break;
00137 case WSAEMFILE: printf(" The queue is nonempty upon entry to accept and there are no descriptors available. \n"); break;
00138 case WSAENOBUFS: printf(" No buffer space is available. \n"); break;
00139 case WSAENOTSOCK: printf(" The descriptor is not a socket. \n"); break;
00140 case WSAEOPNOTSUPP: printf(" The referenced socket is not a type that supports connection-oriented service. \n"); break;
00141 case WSAEWOULDBLOCK: printf(" The socket is marked as nonblocking and no connections are present to be accepted. \n"); break;
00142 }
00143 #else
00144 perror("accept_from: accept() error");
00145 #endif
00146 j_error("failed to accept connection\n");
00147 }
00148 j_printf("connect from %s\n", inet_ntoa(from.sin_addr));
00149 return asd;
00150 }
00151
00160 int
00161 make_connection(char *hostname, int port_num)
00162 {
00163 static struct hostent *hp;
00164 static struct sockaddr_in sin;
00165 int sd;
00166 int trynum;
00167
00168 #ifdef WINSOCK
00169
00170 if (!winsock_initialized) {
00171 WSADATA data;
00172 WSAStartup(0x1010, &data);
00173 winsock_initialized = TRUE;
00174 }
00175 #endif
00176
00177
00178 if ((hp = gethostbyname(hostname)) == NULL) {
00179 j_printerr("make_connection: host not found: %s\n",hostname);
00180 return -3;
00181 }
00182
00183
00184 #ifdef WINSOCK
00185 if((sd = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET){
00186 perror("make_connection: socket() error") ;
00187 printf("Error code: %d\n", WSAGetLastError());
00188 switch(WSAGetLastError()) {
00189 case WSANOTINITIALISED: printf("A successful WSAStartup must occur before using this function.\n"); break;
00190 case WSAENETDOWN: printf("The network subsystem or the associated service provider has failed.\n"); break;
00191 case WSAEAFNOSUPPORT: printf("The specified address family is not supported. \n"); break;
00192 case WSAEINPROGRESS: printf("A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function. \n"); break;
00193 case WSAEMFILE: printf("No more socket descriptors are available. \n"); break;
00194 case WSAENOBUFS: printf("No buffer space is available. The socket cannot be created. \n"); break;
00195 case WSAEPROTONOSUPPORT: printf("The specified protocol is not supported. \n"); break;
00196 case WSAEPROTOTYPE: printf("The specified protocol is the wrong type for this socket. \n"); break;
00197 case WSAESOCKTNOSUPPORT: printf("The specified socket type is not supported in this address family. \n"); break;
00198 }
00199 return -1;
00200 }
00201 #else
00202 if((sd = socket(PF_INET, SOCK_STREAM, 0)) < 0){
00203 perror("make_connection: socket() error") ;
00204 return -1;
00205 }
00206 #endif
00207
00208
00209 for (trynum = 0; trynum < CONNECTION_RETRY_TIMES; trynum++) {
00210 memset((char *)&sin, 0, sizeof(sin));
00211 memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
00212 sin.sin_family = hp->h_addrtype;
00213 sin.sin_port = htons((unsigned short)port_num);
00214 if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) >= 0) {
00215
00216 break;
00217 } else {
00218
00219 perror("make_connection");
00220
00221 j_printerr("retry after %d second...\n", CONNECTION_RETRY_INTERVAL);
00222 sleep(CONNECTION_RETRY_INTERVAL);
00223 }
00224 }
00225 if (trynum == CONNECTION_RETRY_TIMES) {
00226
00227 j_printerr("make_connection: failed to connect to $s:%d\n", hostname, port_num);
00228 return -2;
00229 }
00230
00231 return sd;
00232 }
00233
00234 #ifndef WINSOCK
00235
00243 int
00244 make_connection_unix(char *address)
00245 {
00246 struct sockaddr_un ps;
00247 int len;
00248 int sd;
00249
00250 ps.sun_family = PF_UNIX;
00251 strcpy(ps.sun_path, address);
00252 len = sizeof(ps.sun_family) + strlen(ps.sun_path);
00253
00254 if((sd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0){
00255 perror("make_connection_unix: socket() error");
00256 return -1;
00257 }
00258 while(connect(sd, (struct sockaddr *)&ps, len) < 0){
00259 perror("make_conenction_unix: connect() error");
00260
00261 j_printerr("retry after %d sec...\n",CONNECTION_RETRY_INTERVAL);
00262 sleep(CONNECTION_RETRY_INTERVAL);
00263 }
00264
00265 return sd;
00266 }
00267 #endif
00268
00276 int
00277 close_socket(int sd)
00278 {
00279 int ret;
00280 #ifdef WINSOCK
00281 ret = closesocket(sd);
00282 #else
00283 ret = close(sd);
00284 #endif
00285 return(ret);
00286 }
00287
00292 void
00293 cleanup_socket()
00294 {
00295 #ifdef WINSOCK
00296 if (winsock_initialized) {
00297 WSACleanup();
00298 }
00299 #endif
00300 }