00001
00048 #include "SampleSocketPort.h"
00049
00050 SampleSocketPort::SampleSocketPort(SocketService *pService, TCPSocket & tcpSocket) :
00051 SocketPort(pService, tcpSocket)
00052 {
00053 tpport_t port;
00054 InetHostAddress ia = getPeer( & port );
00055 cerr << "connecting from " << ia.getHostname() << ":" << port << endl;
00056
00057
00058 setCompletion( false );
00059
00060
00061
00062
00063
00064 m_bOpen = true;
00065 m_bDoDisconnect = false;
00066 m_bTimedOut = false;
00067 m_bReceptionStarted = false;
00068 m_nLastBytesAvail = 0;
00069 m_pBuf = new char[MAX_RXBUF];
00070 }
00071
00072
00073 SampleSocketPort::~SampleSocketPort()
00074 {
00075 endSocket();
00076 delete [] m_pBuf;
00077 }
00078
00079 void SampleSocketPort::pending(void)
00080 {
00081
00082 if(!m_bOpen)
00083 return;
00084
00085
00086 int nBytesAvail = peek(m_pBuf, MAX_RXBUF);
00087
00088
00089 if(!m_bReceptionStarted)
00090 {
00091 ResetReadTimeout(MAX_RXTIMEOUT);
00092 m_bReceptionStarted = true;
00093 }
00094 else
00095 {
00096 if(m_bTimedOut)
00097 {
00098 ResetReadTimeout(MAX_RXTIMEOUT);
00099 m_nLastBytesAvail = 0;
00100 m_bReceptionStarted = false;
00101 OnRxTimeout();
00102 return;
00103 }
00104 }
00105
00106 if(m_nLastBytesAvail == nBytesAvail)
00107 {
00108
00109
00110 if(nBytesAvail == 0)
00111 {
00112 if(!m_bDoDisconnect)
00113 {
00114 CloseSocket();
00115 }
00116 }
00117 return;
00118 }
00119
00120
00121
00122
00123
00124
00125 if(nBytesAvail > MAX_RXBUF)
00126 {
00127 cerr << "TCP/IP overflow..." << endl;
00128 FlushRxData();
00129 m_nLastBytesAvail = 0;
00130 m_bReceptionStarted = false;
00131 return;
00132 }
00133 m_nLastBytesAvail = nBytesAvail;
00134
00135
00136
00137
00138 for(int i=0; i < nBytesAvail; i++)
00139 {
00140
00141
00142
00143 if(m_pBuf[i] == '\r')
00144 {
00145 if(i+1 < nBytesAvail)
00146 {
00147 if(m_pBuf[i+1] == '\n')
00148 {
00149
00150
00151
00152
00153 m_nLastBytesAvail = 0;
00154 m_bReceptionStarted = false;
00155
00156
00157
00158 int nLen = i+2;
00159 char *pszRxData = new char[nLen+1];
00160 receive(pszRxData, nLen);
00161 pszRxData[nLen] = '\0';
00162 OnDataReceived(pszRxData, nLen);
00163 delete [] pszRxData;
00164 return;
00165 }
00166 }
00167 }
00168
00169
00170 }
00171 }
00172
00173 void SampleSocketPort::disconnect(void)
00174 {
00175 if(m_bOpen)
00176 {
00177 m_bDoDisconnect = true;
00178 CloseSocket();
00179 }
00180 }
00181
00182 void SampleSocketPort::expired(void)
00183 {
00184 if(m_bDoDisconnect && m_bOpen)
00185 {
00186 CloseSocket();
00187 }
00188 else if(m_bOpen && m_bReceptionStarted)
00189 {
00190
00191 m_bTimedOut = true;
00192 }
00193 }
00194
00195
00196 bool SampleSocketPort::CloseSocket(void)
00197 {
00198 if(m_bOpen && m_bDoDisconnect)
00199 {
00200 m_bOpen = false;
00201 OnConnectionClosed();
00202 delete this;
00203 }
00204 else if(m_bOpen)
00205 {
00206 m_bDoDisconnect = true;
00207 setTimer(DISCONNECT_MS);
00208 }
00209 return(true);
00210 }
00211
00212
00213 ssize_t SampleSocketPort::DoSend(void *buf, size_t len)
00214 {
00215
00216 if(m_bDoDisconnect)
00217 return((ssize_t)len);
00218
00219 ssize_t nSent = send(buf, len);
00220 while(!isPending(Socket::pendingOutput, 0))
00221 {
00222 if(m_bDoDisconnect || !m_bOpen)
00223 {
00224
00225 return((ssize_t)len);
00226 }
00227
00228
00229 Thread::yield();
00230 }
00231 return(nSent);
00232 }
00233
00234 bool SampleSocketPort::WriteData(const char *szTxData, const size_t nByteCount)
00235 {
00236
00237 ssize_t nLen = nByteCount;
00238
00239 if(nLen == -1)
00240 nLen = (ssize_t)strlen(szTxData);
00241
00242 size_t nBytesToSend = nLen;
00243
00244 while(m_bOpen && nLen)
00245 {
00246 nLen -= DoSend((void *)&(szTxData[nBytesToSend - nLen]), nLen);
00247 }
00248
00249
00250
00251
00252
00253 return(true);
00254 }
00255
00256
00257
00258 #define WITH_EXAMPLE
00259
00260 #ifdef WITH_EXAMPLE
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 int g_nOpenPorts = 0;
00286
00287 class ReverserPort : public SampleSocketPort
00288 {
00289 public:
00290 ReverserPort(SocketService *pService, TCPSocket & tcpSocket) :
00291 SampleSocketPort(pService, tcpSocket)
00292 {
00293 g_nOpenPorts++;
00294 }
00295 virtual ~ReverserPort()
00296 {
00297 g_nOpenPorts--;
00298 }
00299 virtual void OnConnectionClosed(void)
00300 { cerr << "Connection Closed!" << endl; }
00301
00306 virtual void OnDataReceived(char *pszData, unsigned int nByteCount)
00307 {
00308
00309
00310 size_t nLen = strlen(pszData);
00311 char *szToSend = new char[nLen+1];
00312
00313
00314 size_t nIndex = nLen-3;
00315
00316 size_t i;
00317 for(i=0; i < nLen - 2; i++)
00318 {
00319 szToSend[i] = pszData[nIndex - i];
00320 }
00321 szToSend[i++] = '\r';
00322 szToSend[i++] = '\n';
00323 szToSend[nLen] = '\0';
00324
00325 WriteData(szToSend, nLen);
00326 delete [] szToSend;
00327 }
00328
00329 };
00330
00331 class ReverserServer : public SampleSocketServiceServer
00332 {
00333 public:
00334 ReverserServer(InetHostAddress & machine, int port) :
00335 TCPSocket(machine, port), Thread(), SampleSocketServiceServer(machine, port)
00336 {
00337 }
00338 virtual ~ReverserServer()
00339 {
00340 }
00341 virtual SocketPort *CreateSocketPort(SocketService *pService, TCPSocket & Socket)
00342 {
00343 return(new ReverserPort(pService, Socket));
00344 }
00345 };
00346
00347
00348 int main(void)
00349 {
00350 InetHostAddress LocalHost;
00351 LocalHost = htonl(INADDR_ANY);
00352 ReverserServer *Server = NULL;
00353 try
00354 {
00355 Server = new ReverserServer(LocalHost, 3999);
00356 Server->StartServer();
00357 }
00358 catch(...)
00359 {
00360 cerr << "Failed to start server" << endl;
00361 return(false);
00362 }
00363 cerr << "Waiting for connections...type \"quit\" to exit." << endl;
00364
00365 char cmd[255];
00366
00367 cin.getline(cmd, 255);
00368
00369
00370 while(strcmp(cmd, "quit") != 0)
00371 {
00372 cin.getline(cmd, 255);
00373 }
00374
00375 Server->StopServer();
00376 delete Server;
00377 return 0;
00378 }
00379
00380 #endif //WITH_EXAMPLE
00381