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