00001 /*************************************************************************** 00002 *cr 00003 *cr (C) Copyright 1995-2019 The Board of Trustees of the 00004 *cr University of Illinois 00005 *cr All Rights Reserved 00006 *cr 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * RCS INFORMATION: 00011 * 00012 * $RCSfile: vmdsock.c,v $ 00013 * $Author: johns $ $Locker: $ $State: Exp $ 00014 * $Revision: 1.31 $ $Date: 2020年12月13日 07:41:55 $ 00015 * 00016 *************************************************************************** 00017 * DESCRIPTION: 00018 * Socket interface, abstracts machine dependent APIs/routines. 00019 * 00020 * LICENSE: 00021 * UIUC Open Source License 00022 * http://www.ks.uiuc.edu/Research/vmd/plugins/pluginlicense.html 00023 * 00024 ***************************************************************************/ 00025 00026 #define VMDSOCKINTERNAL 1 00027 00028 #include <stdio.h> 00029 #include <stdlib.h> 00030 #include <string.h> 00031 00032 #if defined(_MSC_VER) 00033 #include <winsock2.h> 00034 #else 00035 #include <arpa/inet.h> 00036 #include <fcntl.h> 00037 00038 #include <sys/types.h> 00039 #include <unistd.h> /* for Linux */ 00040 #include <sys/socket.h> 00041 #include <netdb.h> 00042 #endif 00043 00044 #include <errno.h> 00045 00046 #include "vmdsock.h" 00047 00048 int vmdsock_init(void) { 00049 #if defined(_MSC_VER) 00050 int rc = 0; 00051 static int initialized=0; 00052 00053 if (!initialized) { 00054 WSADATA wsdata; 00055 rc = WSAStartup(MAKEWORD(1,1), &wsdata); 00056 if (rc == 0) 00057 initialized = 1; 00058 } 00059 00060 return rc; 00061 #else 00062 return 0; 00063 #endif 00064 } 00065 00066 00067 void * vmdsock_create(void) { 00068 vmdsocket * s; 00069 00070 s = (vmdsocket *) malloc(sizeof(vmdsocket)); 00071 if (s != NULL) 00072 memset(s, 0, sizeof(vmdsocket)); 00073 00074 if ((s->sd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { 00075 printf("Failed to open socket."); 00076 free(s); 00077 return NULL; 00078 } 00079 00080 return (void *) s; 00081 } 00082 00083 int vmdsock_connect(void *v, const char *host, int port) { 00084 vmdsocket *s = (vmdsocket *) v; 00085 char address[1030]; 00086 struct hostent *h; 00087 00088 h=gethostbyname(host); 00089 if (h == NULL) 00090 return -1; 00091 sprintf(address, "%d.%d.%d.%d", 00092 (unsigned char) h->h_addr_list[0][0], 00093 (unsigned char) h->h_addr_list[0][1], 00094 (unsigned char) h->h_addr_list[0][2], 00095 (unsigned char) h->h_addr_list[0][3]); 00096 00097 memset(&(s->addr), 0, sizeof(s->addr)); 00098 s->addr.sin_family = PF_INET; 00099 s->addr.sin_addr.s_addr = inet_addr(address); 00100 s->addr.sin_port = htons(port); 00101 00102 return connect(s->sd, (struct sockaddr *) &s->addr, sizeof(s->addr)); 00103 } 00104 00105 int vmdsock_bind(void * v, int port) { 00106 vmdsocket *s = (vmdsocket *) v; 00107 memset(&(s->addr), 0, sizeof(s->addr)); 00108 s->addr.sin_family = PF_INET; 00109 s->addr.sin_port = htons(port); 00110 00111 return bind(s->sd, (struct sockaddr *) &s->addr, sizeof(s->addr)); 00112 } 00113 00114 int vmdsock_listen(void * v) { 00115 vmdsocket *s = (vmdsocket *) v; 00116 return listen(s->sd, 5); 00117 } 00118 00119 void *vmdsock_accept(void * v) { 00120 int rc; 00121 vmdsocket *new_s = NULL, *s = (vmdsocket *) v; 00122 #if defined(ARCH_AIX5) || defined(ARCH_AIX5_64) || defined(ARCH_AIX6_64) 00123 unsigned int len; 00124 #elif defined(SOCKLEN_T) 00125 SOCKLEN_T len; 00126 #elif defined(ARCH_BLUEWATERS) || defined(ARCH_CRAY_XC) || defined(ARCH_CRAY_XK) || defined(ARCH_LINUXALPHA) || defined(ARCH_LINUXAMD64) || defined(ARCH_LINUXARM64) || defined(ARCH_MACOSX) || defined(ARCH_MACOSXARM64) || defined(ARCH_MACOSXX86) || defined(ARCH_MACOSXX86_64) || defined(ARCH_SUMMIT) || defined(ARCH_OPENPOWER) 00127 socklen_t len; 00128 #else 00129 int len; 00130 #endif 00131 00132 len = sizeof(s->addr); 00133 rc = accept(s->sd, (struct sockaddr *) &s->addr, &len); 00134 if (rc >= 0) { 00135 new_s = (vmdsocket *) malloc(sizeof(vmdsocket)); 00136 if (new_s != NULL) { 00137 *new_s = *s; 00138 new_s->sd = rc; 00139 } 00140 } 00141 return (void *)new_s; 00142 } 00143 00144 int vmdsock_write(void * v, const void *buf, int len) { 00145 vmdsocket *s = (vmdsocket *) v; 00146 #if defined(_MSC_VER) 00147 return send(s->sd, (const char*) buf, len, 0); // windows lacks the write() call 00148 #else 00149 return write(s->sd, buf, len); 00150 #endif 00151 } 00152 00153 int vmdsock_read(void * v, void *buf, int len) { 00154 vmdsocket *s = (vmdsocket *) v; 00155 #if defined(_MSC_VER) 00156 return recv(s->sd, (char*) buf, len, 0); // windows lacks the read() call 00157 #else 00158 return read(s->sd, buf, len); 00159 #endif 00160 00161 } 00162 00163 void vmdsock_shutdown(void *v) { 00164 vmdsocket * s = (vmdsocket *) v; 00165 if (s == NULL) 00166 return; 00167 00168 #if defined(_MSC_VER) 00169 shutdown(s->sd, SD_SEND); 00170 #else 00171 shutdown(s->sd, 1); /* complete sends and send FIN */ 00172 #endif 00173 } 00174 00175 void vmdsock_destroy(void * v) { 00176 vmdsocket * s = (vmdsocket *) v; 00177 if (s == NULL) 00178 return; 00179 00180 #if defined(_MSC_VER) 00181 closesocket(s->sd); 00182 #else 00183 close(s->sd); 00184 #endif 00185 free(s); 00186 } 00187 00188 int vmdsock_selread(void *v, int sec) { 00189 vmdsocket *s = (vmdsocket *)v; 00190 fd_set rfd; 00191 struct timeval tv; 00192 int rc; 00193 00194 FD_ZERO(&rfd); 00195 FD_SET(s->sd, &rfd); 00196 memset((void *)&tv, 0, sizeof(struct timeval)); 00197 tv.tv_sec = sec; 00198 do { 00199 rc = select(s->sd+1, &rfd, NULL, NULL, &tv); 00200 } while (rc < 0 && errno == EINTR); 00201 return rc; 00202 00203 } 00204 00205 int vmdsock_selwrite(void *v, int sec) { 00206 vmdsocket *s = (vmdsocket *)v; 00207 fd_set wfd; 00208 struct timeval tv; 00209 int rc; 00210 00211 FD_ZERO(&wfd); 00212 FD_SET(s->sd, &wfd); 00213 memset((void *)&tv, 0, sizeof(struct timeval)); 00214 tv.tv_sec = sec; 00215 do { 00216 rc = select(s->sd + 1, NULL, &wfd, NULL, &tv); 00217 } while (rc < 0 && errno == EINTR); 00218 return rc; 00219 }