Colin Hogben
/
socket-test
Socket server test
main.cpp@6:9c7707692925, 2016-08-26 (annotated)
- Committer:
- Colin Hogben
- Date:
- Fri Aug 26 10:47:03 2016 +0100
- Revision:
- 6:9c7707692925
- Parent:
- 5:2c2f993df16b
- Child:
- 7:b4f40e054a9e
Add ticker; #defines to enable features
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Colin Hogben |
6:9c7707692925 | 1 | //----------------------------------------------------------------------- |
Colin Hogben |
6:9c7707692925 | 2 | // Test TCP socket behaviour |
Colin Hogben |
6:9c7707692925 | 3 | //----------------------------------------------------------------------- |
Colin Hogben |
5:2c2f993df16b | 4 | #include "mbed.h" |
Colin Hogben |
5:2c2f993df16b | 5 | #include "EthernetInterface.h" |
Colin Hogben |
5:2c2f993df16b | 6 | #include "lwip/stats.h" |
Colin Hogben |
5:2c2f993df16b | 7 | |
Colin Hogben |
5:2c2f993df16b | 8 | #ifndef SRV_PORT |
Colin Hogben |
6:9c7707692925 | 9 | #define SRV_PORT 7 |
Colin Hogben |
5:2c2f993df16b | 10 | #endif |
Colin Hogben |
5:2c2f993df16b | 11 | |
Colin Hogben |
6:9c7707692925 | 12 | #define TICK 1 // Enable 1-second tick thread |
Colin Hogben |
6:9c7707692925 | 13 | #define CONSOLE 0 // Enable interactive statistics |
Colin Hogben |
6:9c7707692925 | 14 | #define CONSOLE_WAIT_READABLE 0 // Non-blocking getc (#2515) |
Colin Hogben |
6:9c7707692925 | 15 | #define CONSOLE_YIELD 0 // 0 = busy-wait until time slice |
Colin Hogben |
6:9c7707692925 | 16 | #undef WAIT_BEFORE_RECV // pause before each recv() |
Colin Hogben |
6:9c7707692925 | 17 | #define ECHO_BUF_SIZE 1000 // How much to recv() before send() |
Colin Hogben |
6:9c7707692925 | 18 | |
Colin Hogben |
5:2c2f993df16b | 19 | Serial pc(USBTX, USBRX); |
Colin Hogben |
5:2c2f993df16b | 20 | EthernetInterface eth; |
Colin Hogben |
5:2c2f993df16b | 21 | |
Colin Hogben |
6:9c7707692925 | 22 | void banner(void) |
Colin Hogben |
6:9c7707692925 | 23 | { |
Colin Hogben |
6:9c7707692925 | 24 | printf("== socket-test %s ==\n", __DATE__); |
Colin Hogben |
6:9c7707692925 | 25 | printf("SRV_PORT: %d\n", SRV_PORT); |
Colin Hogben |
6:9c7707692925 | 26 | printf("TICK: %d\n", TICK); |
Colin Hogben |
6:9c7707692925 | 27 | printf("CONSOLE: %d\n", CONSOLE); |
Colin Hogben |
6:9c7707692925 | 28 | #if CONSOLE |
Colin Hogben |
6:9c7707692925 | 29 | printf("CONSOLE_WAIT_READABLE: %d\n", CONSOLE_WAIT_READABLE); |
Colin Hogben |
6:9c7707692925 | 30 | printf("CONSOLE_YIELD: %d\n", CONSOLE_YIELD); |
Colin Hogben |
6:9c7707692925 | 31 | #endif |
Colin Hogben |
6:9c7707692925 | 32 | #ifdef WAIT_BEFORE_RECV |
Colin Hogben |
6:9c7707692925 | 33 | printf("WAIT_BEFORE_RECV: %g\n", WAIT_BEFORE_RECV); |
Colin Hogben |
6:9c7707692925 | 34 | #endif |
Colin Hogben |
6:9c7707692925 | 35 | printf("ECHO_BUF_SIZE: %d\n", ECHO_BUF_SIZE); |
Colin Hogben |
6:9c7707692925 | 36 | } |
Colin Hogben |
6:9c7707692925 | 37 | |
Colin Hogben |
6:9c7707692925 | 38 | #if CONSOLE |
Colin Hogben |
5:2c2f993df16b | 39 | Thread console_thread; |
Colin Hogben |
5:2c2f993df16b | 40 | |
Colin Hogben |
6:9c7707692925 | 41 | void console_run(void) |
Colin Hogben |
5:2c2f993df16b | 42 | { |
Colin Hogben |
5:2c2f993df16b | 43 | int i; |
Colin Hogben |
5:2c2f993df16b | 44 | while (true) { |
Colin Hogben |
6:9c7707692925 | 45 | #if CONSOLE_WAIT_READABLE |
Colin Hogben |
6:9c7707692925 | 46 | while (! pc.readable()) { |
Colin Hogben |
6:9c7707692925 | 47 | #if CONSOLE_YIELD |
Colin Hogben |
6:9c7707692925 | 48 | Thread::yield(); |
Colin Hogben |
6:9c7707692925 | 49 | #endif |
Colin Hogben |
6:9c7707692925 | 50 | } |
Colin Hogben |
6:9c7707692925 | 51 | #endif |
Colin Hogben |
5:2c2f993df16b | 52 | int c = pc.getc(); |
Colin Hogben |
5:2c2f993df16b | 53 | switch (c) { |
Colin Hogben |
5:2c2f993df16b | 54 | default: printf("lwip statistics: *=all" |
Colin Hogben |
5:2c2f993df16b | 55 | " l=LINK a=ETHARP" |
Colin Hogben |
5:2c2f993df16b | 56 | " i=IP f=IPFRAG c=ICMP g=IGMP" |
Colin Hogben |
5:2c2f993df16b | 57 | " u=UDP t=TCP" |
Colin Hogben |
5:2c2f993df16b | 58 | " h=HEAP m=MEMP* p=PCB n=NETBUF/NETCONN" |
Colin Hogben |
5:2c2f993df16b | 59 | " s=SYS\n"); break; |
Colin Hogben |
5:2c2f993df16b | 60 | case '*': stats_display(); break; |
Colin Hogben |
5:2c2f993df16b | 61 | case 'l': LINK_STATS_DISPLAY(); break; |
Colin Hogben |
5:2c2f993df16b | 62 | case 'a': ETHARP_STATS_DISPLAY(); break; |
Colin Hogben |
5:2c2f993df16b | 63 | case 'f': IPFRAG_STATS_DISPLAY(); break; |
Colin Hogben |
5:2c2f993df16b | 64 | case 'i': IP_STATS_DISPLAY(); break; |
Colin Hogben |
5:2c2f993df16b | 65 | case 'c': ICMP_STATS_DISPLAY(); break; |
Colin Hogben |
5:2c2f993df16b | 66 | case 'g': IGMP_STATS_DISPLAY(); break; |
Colin Hogben |
5:2c2f993df16b | 67 | case 'u': UDP_STATS_DISPLAY(); break; |
Colin Hogben |
5:2c2f993df16b | 68 | case 't': TCP_STATS_DISPLAY(); break; |
Colin Hogben |
5:2c2f993df16b | 69 | case 'h': MEM_STATS_DISPLAY(); break; |
Colin Hogben |
5:2c2f993df16b | 70 | case 'm': for (i=0; i < MEMP_MAX; i++) MEMP_STATS_DISPLAY(i); break; |
Colin Hogben |
5:2c2f993df16b | 71 | case 'p': |
Colin Hogben |
5:2c2f993df16b | 72 | MEMP_STATS_DISPLAY(MEMP_UDP_PCB); |
Colin Hogben |
5:2c2f993df16b | 73 | MEMP_STATS_DISPLAY(MEMP_TCP_PCB); |
Colin Hogben |
5:2c2f993df16b | 74 | MEMP_STATS_DISPLAY(MEMP_TCP_PCB_LISTEN); |
Colin Hogben |
5:2c2f993df16b | 75 | break; |
Colin Hogben |
5:2c2f993df16b | 76 | case 'n': |
Colin Hogben |
5:2c2f993df16b | 77 | MEMP_STATS_DISPLAY(MEMP_NETBUF); |
Colin Hogben |
5:2c2f993df16b | 78 | MEMP_STATS_DISPLAY(MEMP_NETCONN); |
Colin Hogben |
5:2c2f993df16b | 79 | break; |
Colin Hogben |
5:2c2f993df16b | 80 | case 's': SYS_STATS_DISPLAY(); break; |
Colin Hogben |
5:2c2f993df16b | 81 | } |
Colin Hogben |
5:2c2f993df16b | 82 | } |
Colin Hogben |
5:2c2f993df16b | 83 | } |
Colin Hogben |
6:9c7707692925 | 84 | #endif |
Colin Hogben |
5:2c2f993df16b | 85 | |
Colin Hogben |
6:9c7707692925 | 86 | #if TICK |
Colin Hogben |
6:9c7707692925 | 87 | Thread tick_thread; |
Colin Hogben |
6:9c7707692925 | 88 | |
Colin Hogben |
6:9c7707692925 | 89 | void tick_run(void) |
Colin Hogben |
5:2c2f993df16b | 90 | { |
Colin Hogben |
6:9c7707692925 | 91 | while (true) { |
Colin Hogben |
6:9c7707692925 | 92 | printf("tick\n"); |
Colin Hogben |
6:9c7707692925 | 93 | wait(1.0); |
Colin Hogben |
6:9c7707692925 | 94 | printf("tock\n"); |
Colin Hogben |
6:9c7707692925 | 95 | wait(1.0); |
Colin Hogben |
6:9c7707692925 | 96 | } |
Colin Hogben |
6:9c7707692925 | 97 | } |
Colin Hogben |
6:9c7707692925 | 98 | #endif |
Colin Hogben |
6:9c7707692925 | 99 | |
Colin Hogben |
6:9c7707692925 | 100 | void echo_conn_run(TCPSocket *sock) |
Colin Hogben |
6:9c7707692925 | 101 | { |
Colin Hogben |
6:9c7707692925 | 102 | static char buf[ECHO_BUF_SIZE]; |
Colin Hogben |
5:2c2f993df16b | 103 | int ret; |
Colin Hogben |
5:2c2f993df16b | 104 | while (true) { |
Colin Hogben |
6:9c7707692925 | 105 | #ifdef WAIT_BEFORE_RECV |
Colin Hogben |
6:9c7707692925 | 106 | wait(WAIT_BEFORE_RECV); |
Colin Hogben |
6:9c7707692925 | 107 | #endif |
Colin Hogben |
5:2c2f993df16b | 108 | ret = sock->recv(buf, sizeof(buf)); |
Colin Hogben |
5:2c2f993df16b | 109 | if (ret < 0) { |
Colin Hogben |
6:9c7707692925 | 110 | printf("recv: %d\n", ret); |
Colin Hogben |
6:9c7707692925 | 111 | break; |
Colin Hogben |
5:2c2f993df16b | 112 | } else if (ret == 0) { |
Colin Hogben |
5:2c2f993df16b | 113 | printf("recv: EOF\r\n"); |
Colin Hogben |
5:2c2f993df16b | 114 | break; |
Colin Hogben |
5:2c2f993df16b | 115 | } else { |
Colin Hogben |
6:9c7707692925 | 116 | int size = ret; |
Colin Hogben |
5:2c2f993df16b | 117 | putchar('<'); fflush(stdout); |
Colin Hogben |
6:9c7707692925 | 118 | ret = sock->send(buf, size); |
Colin Hogben |
5:2c2f993df16b | 119 | if (ret < 0) { |
Colin Hogben |
6:9c7707692925 | 120 | printf("send: %d\n", ret); |
Colin Hogben |
6:9c7707692925 | 121 | break; |
Colin Hogben |
6:9c7707692925 | 122 | } else if (ret < size) { |
Colin Hogben |
6:9c7707692925 | 123 | printf("send: only %d sent\n", ret); |
Colin Hogben |
5:2c2f993df16b | 124 | } else { |
Colin Hogben |
5:2c2f993df16b | 125 | putchar('>'); fflush(stdout); |
Colin Hogben |
5:2c2f993df16b | 126 | } |
Colin Hogben |
5:2c2f993df16b | 127 | } |
Colin Hogben |
5:2c2f993df16b | 128 | } |
Colin Hogben |
6:9c7707692925 | 129 | delete sock; |
Colin Hogben |
5:2c2f993df16b | 130 | } |
Colin Hogben |
5:2c2f993df16b | 131 | |
Colin Hogben |
6:9c7707692925 | 132 | void echo_srv_run(TCPServer *srv) |
Colin Hogben |
5:2c2f993df16b | 133 | { |
Colin Hogben |
5:2c2f993df16b | 134 | int err; |
Colin Hogben |
5:2c2f993df16b | 135 | while (true) { |
Colin Hogben |
5:2c2f993df16b | 136 | TCPSocket *sock = new TCPSocket; |
Colin Hogben |
5:2c2f993df16b | 137 | err = srv->accept(sock); |
Colin Hogben |
5:2c2f993df16b | 138 | if (err) error("accept: %d\r\n", err); |
Colin Hogben |
5:2c2f993df16b | 139 | printf("accepted connection\r\n"); |
Colin Hogben |
5:2c2f993df16b | 140 | Thread *conn_thread = new Thread; |
Colin Hogben |
6:9c7707692925 | 141 | conn_thread->start(Callback<void()>(sock, echo_conn_run)); |
Colin Hogben |
5:2c2f993df16b | 142 | } |
Colin Hogben |
5:2c2f993df16b | 143 | } |
Colin Hogben |
5:2c2f993df16b | 144 | |
Colin Hogben |
5:2c2f993df16b | 145 | int main(void) |
Colin Hogben |
5:2c2f993df16b | 146 | { |
Colin Hogben |
5:2c2f993df16b | 147 | int err; |
Colin Hogben |
6:9c7707692925 | 148 | banner(); |
Colin Hogben |
5:2c2f993df16b | 149 | stats_init(); |
Colin Hogben |
6:9c7707692925 | 150 | #if TICK |
Colin Hogben |
6:9c7707692925 | 151 | tick_thread.start(tick_run); |
Colin Hogben |
6:9c7707692925 | 152 | #endif |
Colin Hogben |
6:9c7707692925 | 153 | #if CONSOLE |
Colin Hogben |
6:9c7707692925 | 154 | console_thread.start(console_run); |
Colin Hogben |
6:9c7707692925 | 155 | #endif |
Colin Hogben |
5:2c2f993df16b | 156 | err = eth.connect(); |
Colin Hogben |
5:2c2f993df16b | 157 | if (err) error("connect: %d\n", err); |
Colin Hogben |
5:2c2f993df16b | 158 | printf("ip %s\r\n", eth.get_ip_address()); |
Colin Hogben |
5:2c2f993df16b | 159 | TCPServer srv; |
Colin Hogben |
5:2c2f993df16b | 160 | err = srv.open(ð); |
Colin Hogben |
5:2c2f993df16b | 161 | if (err) error("open: %d\r\n", err); |
Colin Hogben |
5:2c2f993df16b | 162 | err = srv.bind(SRV_PORT); |
Colin Hogben |
5:2c2f993df16b | 163 | if (err) error("bind: %d\r\n", err); |
Colin Hogben |
5:2c2f993df16b | 164 | err = srv.listen(0); |
Colin Hogben |
5:2c2f993df16b | 165 | if (err) error("listen: %d\r\n", err); |
Colin Hogben |
5:2c2f993df16b | 166 | Thread srv_thread; |
Colin Hogben |
6:9c7707692925 | 167 | srv_thread.start(Callback<void()>(&srv, echo_srv_run)); |
Colin Hogben |
5:2c2f993df16b | 168 | |
Colin Hogben |
5:2c2f993df16b | 169 | while (true) { |
Colin Hogben |
5:2c2f993df16b | 170 | wait(1.0); |
Colin Hogben |
5:2c2f993df16b | 171 | } |
Colin Hogben |
5:2c2f993df16b | 172 | } |