Looking for simple TCPSocket Client Example

04 Apr 2011

I've scoured the forum for a simple tcp sockets client example. Not finding anything I started to write one.

#include "mbed.h"
#include "EthernetNetIf.h"
#include "TCPSocket.h"

DigitalOut myled(LED1);
EthernetNetIf ethernet(
  IpAddr(192,168,0,155), //IP Address
  IpAddr(255,255,255,0), //Network Mask
  IpAddr(192,168,0,1), //Gateway
  IpAddr(192,168,0,1)  //DNS
);
TCPSocket socket;
Host host;
int state;
// JSON message to get a sigle datastream
const char msg[]="{\"method\":\"get\",\"resource\":\"/feeds/1539/datastreams/2\",\"headers\":{\"X-PachubeApiKey\":\""
                 "key here"
                 "\"},\"token\" : \"0x123456\"}}";
char domain[] = "beta.pachube.com";
IpAddr ip=IpAddr(173,203,109,233);
int port=8081;


void send_request(const char* msg) {
  int len=socket.send(msg,strlen(msg));
  // check len==strlen(msg)
  printf("message sent\r\n");
}

void read_data() {
  char buf[2048];
  int len=socket.recv(buf,2048);
  buf[len]='\0';
  printf("received: %s\r\n",buf);
}

void onSocketEvent(TCPSocketEvent e) {
  printf("event:");
  switch(e) {
    case TCPSOCKET_CONNECTED:
        printf("0 connected\r\n");
        break;
    case TCPSOCKET_ACCEPT:
        printf("1 Client is connected, must call accept() to get a new Socket.\r\n");
        // can't find an example of this
        break;
    case TCPSOCKET_READABLE:
        printf("2 Socket readable\r\n");
        read_data();
        break;
    case TCPSOCKET_WRITEABLE:
        printf("3 Socket writeable\r\n");
        send_request(msg);
        break;
    case TCPSOCKET_CONTIMEOUT:     
        printf("4 Connection timed out.\r\n");
        break;
    case TCPSOCKET_CONRST:
        printf("5 Connection was reset by remote host.\r\n");
        break;
    case TCPSOCKET_CONABRT:
        printf("6 Connection was aborted.\r\n");
        state=0;
        break;
    case TCPSOCKET_ERROR:
        printf("7 Unknown error.\r\n");
        break;
    case TCPSOCKET_DISCONNECTED:     
        printf("8 Disconnected.\r\n");
        break;
  }
}

int main() {
    printf("connecting to net ..");
    EthernetErr eerr = ethernet.setup();
    if (eerr){
        printf("error %d\r\n", eerr);  
        return -1;
    }
    myled=1;
    socket.setOnEvent(onSocketEvent);
    host.setPort(port);
    host.setIp(ip);
    host.setName(domain);
    state=1;
    printf("connecting to socket ..\r\n");
    TCPSocketErr serr = socket.connect(host);
    if (serr) {
      printf("error [%d]\r\n", (int) serr);
      return -1;
    }
    printf("waiting for event\r\n");
    while (state) {
      myled=!myled;
      Net::poll();
      wait(1);
    }
    socket.close();
    myled=0;
    while (1) {}
}

It appears to start the ethernet and send the connect request OK. However, the only event I get back is "connection aborted"; That happens after what seems like a minute of waiting. Any ideas?

The second question is about the necessary sequence for a client. It looks as if you can send a message as soon as a "connected" event fires. A call to accept() to get a new socket appears to be needed only for servers - is that right?

Thx. Paul

05 Apr 2011

Hey Paul,

As far as I found out, the idea is that the server is listening on a defined port. The client has to send it's connect request to this specific port. The server will then accept the connection and give the client a new port on which they will communicate. This way the server can continue listening on the defined port while it handles the client.

So you are right that the client doesn't need a defined accept routine.

An example of the mbed playing server with a listening port and a client handling port: http://mbed.org/users/xshige/programs/TCP_server/leamu9/docs/main_8cpp_source.html

What is your mbed trying to connect to?

PS: I'm pretty sure I found a tcp client example on mbed's site but can't find it now. Will link it if I find it.

Regards,

Melchior

06 Apr 2011

Thx Melchior,

I made a little progress, finding that I get a reply if I send a message without waiting to be prompted. I then get back an error message from pachube (complaining about the format of the message) despite the fact that this same message is accepted by the server if I send it via telnet or a php script.

I am wondering if this is a timing thing and also why I only get TCPSOCKET_WRITEABLE *after* sending a request.

Regards, Paul

17 May 2011

I´m wondering the same. Why I only get the TCPSOCKET_WRITEABLE after sending a request...