EthernetInterface, TCP Echo Server, support multi session

Dependencies:   EthernetInterface mbed-rtos mbed

Fork of TCPEchoServer by mbed official

mbed RTOS により、マルチセッションに対応した TCP Echo Server です。

複数のTCP接続を受付け、処理することができます。

accept の後に fork (スレッドを生成)しています。

Committer:
okini3939
Date:
Thu Nov 07 01:44:20 2013 +0000
Revision:
8:46437b951a2f
Parent:
7:0a3cf89d5b93
re-use thread

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 0:38cbb854d85f 1 #include "mbed.h"
okini3939 7:0a3cf89d5b93 2 #include "rtos.h"
emilmont 1:5cebe0e38cd2 3 #include "EthernetInterface.h"
emilmont 1:5cebe0e38cd2 4
okini3939 7:0a3cf89d5b93 5 #define ECHO_SERVER_PORT 10000
okini3939 7:0a3cf89d5b93 6
okini3939 8:46437b951a2f 7 #define THREAD_MAX 5
okini3939 7:0a3cf89d5b93 8 Thread *threads[THREAD_MAX];
okini3939 8:46437b951a2f 9 Thread *xthread;
okini3939 7:0a3cf89d5b93 10
okini3939 7:0a3cf89d5b93 11 void child (void const *arg) {
okini3939 7:0a3cf89d5b93 12 int i;
okini3939 7:0a3cf89d5b93 13 char buf[256];
okini3939 7:0a3cf89d5b93 14 TCPSocketConnection *client = (TCPSocketConnection*)arg;
emilmont 3:36fd3cfad85a 15
okini3939 7:0a3cf89d5b93 16 for (;;) {
okini3939 8:46437b951a2f 17 printf("Connection from %s\r\n", client->get_address());
okini3939 8:46437b951a2f 18 // client->set_blocking(false, 1500); // Timeout after (1.5)s
okini3939 8:46437b951a2f 19 for (;;) {
okini3939 8:46437b951a2f 20 i = client->receive(buf, sizeof(buf));
okini3939 8:46437b951a2f 21 if (i < 0) break;
okini3939 8:46437b951a2f 22 if (i == 0) continue;
okini3939 8:46437b951a2f 23 buf[i] = 0;
okini3939 8:46437b951a2f 24 printf("Recv '%s'\r\n", buf);
okini3939 8:46437b951a2f 25 if (client->send(buf, i) < 0) break;
okini3939 8:46437b951a2f 26 }
okini3939 8:46437b951a2f 27
okini3939 8:46437b951a2f 28 client->close();
okini3939 8:46437b951a2f 29 printf("Close %s\r\n", client->get_address());
okini3939 8:46437b951a2f 30
okini3939 8:46437b951a2f 31 Thread::signal_wait(1);
okini3939 7:0a3cf89d5b93 32 }
okini3939 8:46437b951a2f 33 }
okini3939 7:0a3cf89d5b93 34
okini3939 8:46437b951a2f 35 void closer (void const *arg) {
okini3939 8:46437b951a2f 36 TCPSocketConnection *client = (TCPSocketConnection*)arg;
okini3939 8:46437b951a2f 37
okini3939 8:46437b951a2f 38 for (;;) {
okini3939 8:46437b951a2f 39 client->close();
okini3939 8:46437b951a2f 40 printf("Close %s\r\n", client->get_address());
okini3939 8:46437b951a2f 41
okini3939 8:46437b951a2f 42 Thread::signal_wait(1);
okini3939 8:46437b951a2f 43 }
okini3939 7:0a3cf89d5b93 44 }
okini3939 7:0a3cf89d5b93 45
okini3939 7:0a3cf89d5b93 46 void parent () {
okini3939 7:0a3cf89d5b93 47 int i, t = 0;
okini3939 8:46437b951a2f 48 TCPSocketConnection clients[THREAD_MAX];
okini3939 8:46437b951a2f 49 TCPSocketConnection xclient;
okini3939 7:0a3cf89d5b93 50
okini3939 7:0a3cf89d5b93 51 for (i = 0; i < THREAD_MAX; i ++) {
okini3939 7:0a3cf89d5b93 52 threads[i] = NULL;
okini3939 7:0a3cf89d5b93 53 }
okini3939 8:46437b951a2f 54 xthread = NULL;
okini3939 7:0a3cf89d5b93 55
emilmont 1:5cebe0e38cd2 56 TCPSocketServer server;
emilmont 3:36fd3cfad85a 57 server.bind(ECHO_SERVER_PORT);
emilmont 3:36fd3cfad85a 58 server.listen();
okini3939 7:0a3cf89d5b93 59
okini3939 7:0a3cf89d5b93 60 printf("Wait for new connection...\r\n");
okini3939 7:0a3cf89d5b93 61 for (;;) {
okini3939 7:0a3cf89d5b93 62 if (t >= 0) {
okini3939 8:46437b951a2f 63 server.accept(clients[t]);
okini3939 7:0a3cf89d5b93 64 // fork child process
okini3939 8:46437b951a2f 65 if (threads[t]) {
okini3939 8:46437b951a2f 66 threads[t]->signal_set(1);
okini3939 8:46437b951a2f 67 } else {
okini3939 8:46437b951a2f 68 threads[t] = new Thread(child, (void*)&clients[t]);
okini3939 8:46437b951a2f 69 }
okini3939 7:0a3cf89d5b93 70 printf("Forked %d\r\n", t);
okini3939 8:46437b951a2f 71 } else {
okini3939 8:46437b951a2f 72 server.accept(xclient);
okini3939 8:46437b951a2f 73 // closer process
okini3939 8:46437b951a2f 74 if (xthread) {
okini3939 8:46437b951a2f 75 xthread->signal_set(1);
okini3939 8:46437b951a2f 76 } else {
okini3939 8:46437b951a2f 77 xthread = new Thread(closer, (void*)&xclient);
okini3939 8:46437b951a2f 78 }
okini3939 8:46437b951a2f 79 printf("Connection full\r\n");
emilmont 1:5cebe0e38cd2 80 }
okini3939 8:46437b951a2f 81
okini3939 7:0a3cf89d5b93 82 t = -1;
okini3939 7:0a3cf89d5b93 83 for (i = 0; i < THREAD_MAX; i ++) {
okini3939 8:46437b951a2f 84 /*
okini3939 7:0a3cf89d5b93 85 if (threads[i]) {
okini3939 7:0a3cf89d5b93 86 if (threads[i]->get_state() == Thread::Inactive) {
okini3939 7:0a3cf89d5b93 87 // terminate process
okini3939 7:0a3cf89d5b93 88 // delete threads[i];
okini3939 7:0a3cf89d5b93 89 // threads[i] = NULL;
okini3939 7:0a3cf89d5b93 90 printf("Terminated %d\r\n", i);
okini3939 7:0a3cf89d5b93 91 }
okini3939 7:0a3cf89d5b93 92 }
okini3939 8:46437b951a2f 93 */
okini3939 8:46437b951a2f 94 if (threads[i] == NULL || threads[i]->get_state() == Thread::WaitingAnd) {
okini3939 8:46437b951a2f 95 if (t < 0) t = i; // next empty thread
okini3939 7:0a3cf89d5b93 96 }
okini3939 7:0a3cf89d5b93 97 }
emilmont 1:5cebe0e38cd2 98 }
emilmont 1:5cebe0e38cd2 99 }
okini3939 7:0a3cf89d5b93 100
okini3939 7:0a3cf89d5b93 101
okini3939 7:0a3cf89d5b93 102 int main () {
okini3939 7:0a3cf89d5b93 103 EthernetInterface eth;
okini3939 7:0a3cf89d5b93 104 printf("TCP Echo Server with Fork...\r\n");
okini3939 7:0a3cf89d5b93 105 eth.init(); //Use DHCP
okini3939 8:46437b951a2f 106 if (eth.connect()) return -1;
okini3939 7:0a3cf89d5b93 107 printf("IP Address is %s\r\n", eth.getIPAddress());
okini3939 7:0a3cf89d5b93 108
okini3939 7:0a3cf89d5b93 109 parent();
okini3939 7:0a3cf89d5b93 110 }