00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "ArExport.h"
00027 #include "ariaOSDef.h"
00028 #include "ArSocket.h"
00029 #include "ArLog.h"
00030
00031
00032 void ArSocket::internalInit(void)
00033 {
00034 myCloseFunctor = NULL;
00035 myStringAutoEcho = true;
00036 myStringEcho = false;
00037 myStringPosLast = 0;
00038 myStringPos = 0;
00039 myStringGotComplete = false;
00040 myStringBufEmpty[0] = '\0';
00041 myStringGotEscapeChars = false;
00042 myStringHaveEchoed = false;
00043 sprintf(myIPString, "none");
00044 resetTracking();
00045 }
00046
00047 AREXPORT int ArSocket::sendTo(const void *msg, int len)
00048 {
00049 int ret;
00050 ret = ::sendto(myFD, (char*)msg, len, 0, (struct sockaddr*)&mySin,
00051 sizeof(mySin));
00052 if (ret > 0)
00053 {
00054 mySends++;
00055 myBytesSent += ret;
00056 }
00057 return ret;
00058 }
00059
00060 AREXPORT int ArSocket::sendTo(const void *msg, int len,
00061 struct sockaddr_in *sin)
00062 {
00063 int ret;
00064 ret = ::sendto(myFD, (char*)msg, len, 0, (struct sockaddr*)sin,
00065 sizeof(struct sockaddr_in));
00066 if (ret > 0)
00067 {
00068 mySends++;
00069 myBytesSent += ret;
00070 }
00071 return ret;
00072 }
00073
00074
00075 AREXPORT int ArSocket::recvFrom(void *msg, int len, sockaddr_in *sin)
00076 {
00077
00078 #ifdef WIN32
00079 int i=sizeof(sockaddr_in);
00080 #else
00081 socklen_t i=sizeof(sockaddr_in);
00082 #endif
00083 int ret;
00084 ret = ::recvfrom(myFD, (char*)msg, len, 0, (struct sockaddr*)sin, &i);
00085 if (ret > 0)
00086 {
00087 myRecvs++;
00088 myBytesRecvd += ret;
00089 }
00090 return ret;
00091 }
00092
00098 AREXPORT int ArSocket::write(const void *buff, size_t len)
00099 {
00100
00101 if (myFD < 0)
00102 {
00103 ArLog::log(ArLog::Terse, "ArSocket::write: called after socket closed");
00104 return 0;
00105 }
00106
00107 struct timeval tval;
00108 fd_set fdSet;
00109 tval.tv_sec = 0;
00110 tval.tv_usec = 0;
00111 FD_ZERO(&fdSet);
00112 FD_SET(myFD, &fdSet);
00113
00114
00115 if (select(myFD + 1, NULL, &fdSet, NULL, &tval) <= 0)
00116 return 0;
00117
00118 int ret;
00119 #ifdef WIN32
00120 ret = ::send(myFD, (char*)buff, len, 0);
00121 #else
00122 ret = ::write(myFD, (char*)buff, len);
00123 #endif
00124
00125 if (ret > 0)
00126 {
00127 mySends++;
00128 myBytesSent += ret;
00129 }
00130 return ret;
00131 }
00132
00139 AREXPORT int ArSocket::read(void *buff, size_t len, unsigned int msWait)
00140 {
00141 if (myFD < 0)
00142 {
00143 ArLog::log(ArLog::Terse, "ArSocket::read: called after socket closed");
00144 return 0;
00145 }
00146
00147 int ret;
00148 if (msWait != 0)
00149 {
00150 struct timeval tval;
00151 fd_set fdSet;
00152 tval.tv_sec = msWait / 1000;
00153 tval.tv_usec = (msWait % 1000) * 1000;
00154 FD_ZERO(&fdSet);
00155 FD_SET(myFD, &fdSet);
00156 if (select(myFD + 1, &fdSet, NULL, NULL, &tval) <= 0)
00157 return 0;
00158 }
00159 ret = ::recv(myFD, (char*)buff, len, 0);
00160 if (ret > 0)
00161 {
00162 myRecvs++;
00163 myBytesRecvd += ret;
00164 }
00165 return ret;
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175 AREXPORT int ArSocket::writeString(const char *str, ...)
00176 {
00177 char buf[1200];
00178 int len;
00179 int ret;
00180 myWriteStringMutex.lock();
00181 va_list ptr;
00182 va_start(ptr, str);
00183 vsnprintf(buf, sizeof(buf), str, ptr);
00184 va_end(ptr);
00185 if (myLogWriteStrings)
00186 ArLog::log(ArLog::Normal, "Sent to %s: %s", getIPString(), buf);
00187 len = strlen(buf);
00188 buf[len] = '\n';
00189 len++;
00190 buf[len] = '\r';
00191 len++;
00192 ret = write(buf, len);
00193 myWriteStringMutex.unlock();
00194 return ret;
00195 }
00196
00197 void ArSocket::setIPString(void)
00198 {
00199 unsigned char *bytes;
00200 bytes = (unsigned char *)inAddr();
00201 if (bytes != NULL)
00202 sprintf(myIPString, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
00203 }
00204
00205
00216 AREXPORT char *ArSocket::readString(void)
00217 {
00218 size_t i;
00219 int n;
00220
00221 myReadStringMutex.lock();
00222 myStringBufEmpty[0] = '\0';
00223
00224
00225 for (i = myStringPos; i < sizeof(myStringBuf); i++)
00226 {
00227
00228 n = read(&myStringBuf[i], 1);
00229 if (n > 0)
00230 {
00231 if (i == 0 && myStringBuf[i] < 0)
00232 {
00233 myStringGotEscapeChars = true;
00234 }
00235 if (myStringBuf[i] == '\n' || myStringBuf[i] == '\r')
00236 {
00237 if (i != 0)
00238 myStringGotComplete = true;
00239 myStringBuf[i] = '\0';
00240 myStringPos = 0;
00241 myStringPosLast = 0;
00242
00243 if (myStringBuf[0] < 0)
00244 {
00245 int ei;
00246 myStringGotEscapeChars = true;
00247
00248 for (ei = 0;
00249 myStringBuf[ei] < 0 || (ei > 0 && myStringBuf[ei - 1] < 0);
00250 ei++);
00251
00252 doStringEcho();
00253 myReadStringMutex.unlock();
00254 return &myStringBuf[ei];
00255 }
00256
00257 doStringEcho();
00258 myReadStringMutex.unlock();
00259 return myStringBuf;
00260 }
00261
00262 else
00263 continue;
00264 }
00265
00266 else if (n == 0)
00267 {
00268 myReadStringMutex.unlock();
00269 return NULL;
00270 }
00271 else
00272 {
00273 #ifdef WIN32
00274 if (WSAGetLastError() == WSAEWOULDBLOCK)
00275 {
00276 myStringPos = i;
00277 doStringEcho();
00278 myReadStringMutex.unlock();
00279 return myStringBufEmpty;
00280 }
00281 #endif
00282 #ifndef WIN32
00283 if (errno == EAGAIN)
00284 {
00285 myStringPos = i;
00286 doStringEcho();
00287 myReadStringMutex.unlock();
00288 return myStringBufEmpty;
00289 }
00290 #endif
00291 perror("Error in reading from network");
00292 myReadStringMutex.unlock();
00293 return NULL;
00294 }
00295 }
00296
00297 ArLog::log(ArLog::Normal, "Some trouble in ArSocket::readString to %s", getIPString());
00298 writeString("String too long");
00299 myReadStringMutex.unlock();
00300 return NULL;
00301 }
00302
00303 void ArSocket::doStringEcho(void)
00304 {
00305 size_t to;
00306
00307 if (!myStringAutoEcho && !myStringEcho)
00308 return;
00309
00310
00311 if (myStringHaveEchoed && myStringGotComplete)
00312 {
00313 write("\n\r", 2);
00314 myStringGotComplete = false;
00315 }
00316
00317
00318 if (myStringPosLast == myStringPos)
00319 return;
00320
00321
00322 if (myStringAutoEcho && myStringGotEscapeChars)
00323 return;
00324
00325 myStringHaveEchoed = true;
00326 to = strchr(myStringBuf, '\0') - myStringBuf;
00327 write(&myStringBuf[myStringPosLast], myStringPos - myStringPosLast);
00328 myStringPosLast = myStringPos;
00329 }
00330