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
00027 #if !defined(AFX_SOCKET_H__C0DFE1C7_F17D_4EA0_A890_F0C980247837__INCLUDED_)
00028 #define AFX_SOCKET_H__C0DFE1C7_F17D_4EA0_A890_F0C980247837__INCLUDED_
00029
00030 #include "Object.h"
00031 #include "JString.h"
00032 #include "JTime.h"
00033 #include "JThread.h"
00034 #include "TCPLocation.h"
00035 #include "Debug.h"
00036 #include "TimeSeries.h"
00037
00038 #if _MSC_VER > 1000
00039 #pragma once
00040 #endif // _MSC_VER > 1000
00041
00042 #define READTIMEOUT 10
00043 #ifndef _WIN32_WCE
00044 #ifndef CYGWIN
00045 #define SD_BOTH 2
00046 #endif
00047 #endif
00048
00049 #ifdef WIN32
00050 #define EINPROGRESS WSAEWOULDBLOCK
00051
00052
00053 #define BUFFERSIZE 10000
00054 #define SENDBUFFERSIZE 80000
00055
00056 #if defined(CYGWIN)
00057 #include <windows.h>
00058 #endif
00059 #include <Iphlpapi.h>
00060
00061 #else
00062
00063
00064 #define BUFFERSIZE 10000
00065 #define SENDBUFFERSIZE 80000
00066 #include <errno.h>
00067 #include <sys/types.h>
00068 #include <sys/socket.h>
00069 #include <netinet/tcp.h>
00070 #include <unistd.h>
00071 #include <fcntl.h>
00072 #include <netinet/in.h>
00073 #include <arpa/inet.h>
00074 #include <netdb.h>
00075 #include <sys/ioctl.h>
00076 #include <net/if.h>
00077 #include <ifaddrs.h>
00078
00079 #define NIPQUAD(addr) ((unsigned char *)&addr)[0], \
00080 ((unsigned char *)&addr)[1], \
00081 ((unsigned char *)&addr)[2], \
00082 ((unsigned char *)&addr)[3]
00083
00084 typedef int SOCKET;
00085 #define INVALID_SOCKET -1
00086 #define SOCKET_ERROR -1
00087 #define WSAEWOULDBLOCK EAGAIN
00088 #define WSAEMSGSIZE 11
00089
00090 #define WSAENOTCONN 10057
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 #endif // WIN32
00116
00117
00118 namespace cmlabs {
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 class JSocket : public Object
00133 {
00134 public:
00135
00136 static bool isIPAddressPrivate(JString addr);
00137
00138
00139
00140
00141
00142
00143
00144
00145 JSocket(JString addr, int portnumber, JString protocolname = "");
00146
00147
00148
00149
00150
00151
00152 JSocket(const TCPLocation& loc, JString protocolname = "");
00153
00154
00155
00156
00157
00158
00159 JSocket(SOCKET new_sock);
00160
00161 virtual ~JSocket();
00162
00163 Object* clone() const {return NULL;}
00164
00165 bool setUpListening();
00166
00167
00168 JSocket* waitForConnection(long timeout);
00169
00170
00171 bool connectNow();
00172
00173
00174 bool connectNow(const IPNumber& ip, int port);
00175
00176
00177 bool disconnectNow();
00178
00179
00180 bool terminate();
00181
00182 int flush();
00183
00184
00185
00186
00187
00188
00189
00190
00191 int read(char* buffer, int maxcount, long timeout);
00192
00193
00194
00195
00196
00197
00198 JString readString(int count, long timeout);
00199
00200
00201
00202
00203
00204 JString readln(long timeout);
00205
00206
00207
00208
00209
00210 int write(JString str);
00211
00212
00213
00214
00215
00216
00217 int write(char* ch, int len);
00218
00219
00220
00221
00222
00223 int writeln(JString str);
00224
00225 void setNonBlockingMode();
00226 void setBlockingMode();
00227
00228 JString getLocalIPAddress();
00229 Collection getLocalIPAddresses();
00230 Dictionary getLocalInterfaceAddresses();
00231 JString getLocalHostname();
00232 JString getRemoteHostname();
00233 JString getRemoteIPAddress();
00234 JString getIPAddressFromName(JString name);
00235 IPNumber getIPNumberFromName(JString name);
00236 JString getHostnameFromIPAddress(JString ipaddr);
00237
00238
00239 TCPLocation location;
00240 JString address;
00241 JString localhostName;
00242 int port;
00243 JString protocol;
00244 JString lastErrorMessage;
00245
00246
00247
00248
00249
00250 IPNumber ipnumber;
00251 char charBuffer[BUFFERSIZE+8];
00252
00253 int charBufferCount;
00254 JString stringBuffer;
00255
00256 bool connected;
00257 bool lastErrorRecoverable;
00258 bool listening;
00259
00260
00261
00262
00263 bool isConnected(int timeout = 0);
00264
00265
00266 bool waitForReadability(int timeout);
00267
00268
00269 bool waitForWriteability(int timeout);
00270
00271
00272 bool didConnectionGoThrough(int timeout);
00273
00274
00275 bool isListening();
00276
00277
00278 bool isLastErrorRecoverable();
00279
00280
00281 JString getLastErrorMessage();
00282
00283
00284 int getLastOSErrorNumber();
00285
00286
00287 void osCloseSocket(SOCKET thisSocket);
00288
00289
00290 bool isSocketValid();
00291 bool setSocketNotValid();
00292
00293
00294
00295 SOCKET mySocket;
00296 bool createSocket();
00297 void dealWithSocketError(int wsaError, JString intro = "");
00298
00299 int peekIntoStream();
00300 int peekIntoStream(char* buffer, int maxcount);
00301 int readIntoBuffer();
00302 int readChar(char* ch);
00303 int writeString(JString text);
00304 int writeBuffer(char* buf, int length);
00305
00306 double getSendProgress();
00307 int currentUnsentBufferSize;
00308 int currentSentBufferSize;
00309
00310 double getReceiveProgress();
00311 int currentUnreceivedBufferSize;
00312 int currentReceivedBufferSize;
00313
00314 long getSendBufferSize();
00315 long getReadBufferSize();
00316
00317 double ioCounts[2];
00318 double* getIOCounts();
00319 bool resetIOCounts();
00320
00321 #ifdef WIN32
00322
00323 #else
00324
00325 #endif
00326
00327 Collection localIPAddresses;
00328 JString localIPAddress;
00329
00330 JMutex mutex;
00331 bool isTerminating;
00332 };
00333
00334
00335
00336
00337
00338
00339
00340 class SocketTester : public JThread, public Object
00341 {
00342 public:
00343 SocketTester(int port);
00344 virtual ~SocketTester();
00345 Object* clone() const {return NULL;}
00346
00347 void run();
00348 bool unitTest();
00349
00350 bool shouldContinue;
00351 int portnum;
00352 JSocket* server;
00353 };
00354
00355
00356 class ConnectionProfile : public Object {
00357 public:
00358 ConnectionProfile(JString name = "");
00359 ConnectionProfile(const ConnectionProfile& profile);
00360 ConnectionProfile(XMLNode* node);
00361 Object* clone() const;
00362 bool equals(const Object* obj) const;
00363 bool fromXML(XMLNode* node);
00364 JString toXML();
00365 JString print();
00366 JString toHTML();
00367
00368 const ConnectionProfile& operator = (const ConnectionProfile& profile);
00369
00370 bool setSpeed(long upbps, long downbps);
00371 bool addDataStat(long upbytes, long downbytes, const JTime& time = JTime());
00372
00373 long getSpeedUpload();
00374 long getSpeedDownload();
00375
00376 long getAvgUpload();
00377 long getAvgDownload();
00378
00379 long getMaxAvgUpload();
00380 long getMaxAvgDownload();
00381
00382 double getTotalUpload();
00383 double getTotalDownload();
00384 long getTotalUploadCount();
00385 long getTotalDownloadCount();
00386
00387 int maxConnectionHistory;
00388 bool isDirectlyConnected;
00389
00390 JString getSpeedString();
00391 JString getRateString();
00392 JString getMaxRateString();
00393 JString getTotalString();
00394
00395 JTime getLastActivity();
00396
00397 JString name;
00398
00399 private:
00400
00401 bool recalc();
00402
00403 long speedUploadBps;
00404 long speedDownloadBps;
00405
00406 long avgUploadBps;
00407 long avgDownloadBps;
00408
00409 long maxAvgUploadBps;
00410 long maxAvgDownloadBps;
00411
00412 double totalUpload;
00413 double totalDownload;
00414
00415 long totalUploadCount;
00416 long totalDownloadCount;
00417
00418 TimeSeries uploadHistory;
00419 TimeSeries downloadHistory;
00420 };
00421
00422 }
00423
00424 #endif // !defined(AFX_SOCKET_H__C0DFE1C7_F17D_4EA0_A890_F0C980247837__INCLUDED_)