A simple class to do line-based TCP communication. To be used with the NetServicesMin library-.

Dependents:   pop3demo

Revision:
0:f2727a16072f
Child:
1:28416a5a4ec5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tcplinestream.cpp	Sat Jan 29 22:42:14 2011 +0000
@@ -0,0 +1,169 @@
+#include "Timer.h"
+
+#include "tcplinestream.h"
+
+#include "dnsresolve.h"
+
+void TCPLineStream::onTCPSocketEvent(TCPSocketEvent e) {
+//    printf("New TCPSocketEvent: %d\n",e);
+    switch (e) {
+        case TCPSOCKET_CONNECTED:
+            _connected = true;
+            _connecting=false;
+            break;
+
+        case TCPSOCKET_READABLE:
+            break;
+        case TCPSOCKET_WRITEABLE:
+            break;
+
+        case TCPSOCKET_CONTIMEOUT:
+        case TCPSOCKET_CONRST:
+        case TCPSOCKET_CONABRT:
+        case TCPSOCKET_ERROR:
+        case TCPSOCKET_DISCONNECTED: {
+            // don't close the real socket here, as this may skip the already received data
+            _connected = false;
+            _connecting=false;
+        }
+        break;
+    }
+}
+
+TCPLineStream::TCPLineStream(const char *server, int port, const char* term) {
+    _server=server;
+    _port=port;
+    _term=term;
+}
+
+bool TCPLineStream::open() {
+    _closed=false;
+    _readpos=0;
+    _readlen=0;
+
+    _socket=new TCPSocket();
+    _socket->setOnEvent(this,&TCPLineStream::onTCPSocketEvent);
+
+    IpAddr addr;
+    // ignore IP adress - is !null even if it is 0.0.0.0
+    // so do DNS if a name is given
+    if (NULL!=_server) {
+//    printf("do DNS request for %s\n",_server);
+        DNSResolver dr;
+        addr=dr.resolveName(_server);
+    }
+//    printf("server=%i.%i.%i.%i/%i\n",addr[0],addr[1],addr[2],addr[3],_port);
+
+    Host host(addr, _port);
+
+//    printf("connect\n");
+    TCPSocketErr bindErr = _socket->connect(host);
+
+    if (bindErr != 0) {
+        printf("connection bind error %i\n", bindErr);
+        return false;
+    }
+//    printf("connecting\n");
+    // wait for connection established
+    _connecting=true;
+    mbed::Timer tmr;
+    tmr.start();
+    tmr.reset();
+
+    while (_connecting) {
+        Net::poll();
+        wait_us(100);
+        if (tmr.read()>20) {
+            printf("error: reached timeout\n");
+            break;
+        }
+    }
+    if (!_connected) {
+        printf("error - could not connect (timeout)\n");
+        return false;
+    }
+//    printf("connected\n");
+    return true;
+}
+
+void TCPLineStream::sendLine(string line) {
+//    printf("send request[%s]\n",line.c_str());
+    _socket->send(line.append(_term).c_str(),line.length()+strlen(_term));
+    Net::poll();
+}
+
+void TCPLineStream::close() {
+    if (_closed)
+        return;
+
+    while (_connected) {
+        Net::poll();
+        // read remaining data
+        int err=_socket->recv(_readbuf,BUFSIZE-1);
+        if (err<=0)
+            break;
+    }
+
+    while (true) {
+        Net::poll();
+        // read remaining data
+        int err=_socket->recv(_readbuf,BUFSIZE-1);
+        if (err<=0)
+            break;
+    }
+
+    _socket->resetOnEvent();
+    _socket->close();
+    delete _socket;
+    _closed=true;
+}
+
+string TCPLineStream::readLine(int strLen) {
+    string r;
+    r.reserve(strLen);
+
+    int emptyCount=0;
+    int lineendPos=0;
+    while (true) {
+        Net::poll();
+        if (_readlen>_readpos) {
+            while (_readbuf[_readpos]!=0 && _readpos<_readlen) {
+                char c=_readbuf[_readpos++];
+                //if the current char is the right one of the line terminator sequence
+                if (c==_term[lineendPos]) {
+                    lineendPos++;
+                    if (0==_term[lineendPos]) { // last char of term sequence -> finished
+                        return r;
+                    }
+                } else { // other characters
+                    int i=0;
+                    while (i<lineendPos) // add missed characters from term to string, if there are any
+                        r.push_back(_term[i++]);
+                    lineendPos=0;
+                    r.push_back(c);
+                }
+            }
+        } else {
+            int err=_socket->recv(_readbuf,BUFSIZE-1);
+            if (err < 0) {
+                printf("error while receiving data: %i!\n",err);
+                break;
+            } else if (err>0) {
+                emptyCount=0;
+                _readbuf[err]=0;
+                _readlen=err;
+                _readpos=0;
+//                printf("r=%s\n",_readbuf);
+            } else {
+                // when we don't receive any data, and are not connected
+                // we stop because there isn't anything left
+                if (emptyCount++>2)
+                    if (!_connected)
+                        break;
+            }
+        }
+        wait_us(100);
+    }
+    return r;
+}
+