2011-04-07 11:02:54 +02:00
|
|
|
#include "../oio.h"
|
2011-04-05 01:43:17 +02:00
|
|
|
#include "test.h"
|
2011-03-28 01:55:29 -07:00
|
|
|
#include <stdio.h>
|
2011-03-28 03:26:00 -07:00
|
|
|
#include <stdlib.h>
|
2011-03-28 01:55:29 -07:00
|
|
|
|
2011-03-28 03:17:52 -07:00
|
|
|
#define BUFSIZE 1024
|
2011-03-28 01:55:29 -07:00
|
|
|
|
|
|
|
typedef struct {
|
2011-04-07 11:02:54 +02:00
|
|
|
oio_handle handle;
|
|
|
|
oio_req req;
|
|
|
|
oio_buf buf;
|
2011-03-28 03:17:52 -07:00
|
|
|
char read_buffer[BUFSIZE];
|
2011-03-28 01:55:29 -07:00
|
|
|
} peer_t;
|
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
oio_handle server;
|
2011-03-28 01:55:29 -07:00
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
void after_write(oio_req* req);
|
|
|
|
void after_read(oio_req* req, size_t nread);
|
2011-03-28 01:55:29 -07:00
|
|
|
void try_read(peer_t* peer);
|
2011-04-07 11:02:54 +02:00
|
|
|
void on_close(oio_handle* peer, oio_err err);
|
|
|
|
void on_accept(oio_handle* handle);
|
2011-04-01 00:09:06 +02:00
|
|
|
|
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
void after_write(oio_req* req) {
|
2011-04-07 04:51:59 +02:00
|
|
|
peer_t* peer = (peer_t*) req->data;
|
2011-03-31 14:22:20 +02:00
|
|
|
try_read(peer);
|
2011-03-28 01:55:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
void after_read(oio_req* req, size_t nread) {
|
2011-04-07 04:51:59 +02:00
|
|
|
peer_t* peer;
|
|
|
|
|
2011-03-31 14:22:20 +02:00
|
|
|
if (nread == 0) {
|
2011-04-07 11:02:54 +02:00
|
|
|
oio_close(req->handle);
|
2011-03-31 14:22:20 +02:00
|
|
|
} else {
|
2011-04-07 04:51:59 +02:00
|
|
|
peer = (peer_t*) req->data;
|
2011-03-31 14:22:20 +02:00
|
|
|
peer->buf.len = nread;
|
2011-04-07 11:02:54 +02:00
|
|
|
oio_req_init(&peer->req, &peer->handle, after_write);
|
2011-04-07 04:51:59 +02:00
|
|
|
peer->req.data = peer;
|
2011-04-15 03:32:55 +02:00
|
|
|
if (oio_write(&peer->req, &peer->buf, 1))
|
|
|
|
FATAL(oio_write failed)
|
2011-03-28 01:55:29 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void try_read(peer_t* peer) {
|
|
|
|
peer->buf.len = BUFSIZE;
|
2011-04-07 11:02:54 +02:00
|
|
|
oio_req_init(&peer->req, &peer->handle, after_read);
|
2011-04-07 04:51:59 +02:00
|
|
|
peer->req.data = peer;
|
2011-04-15 03:32:55 +02:00
|
|
|
if (oio_read(&peer->req, &peer->buf, 1))
|
|
|
|
FATAL(oio_read failed)
|
2011-03-28 01:55:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
void on_close(oio_handle* peer, oio_err err) {
|
2011-03-28 01:55:29 -07:00
|
|
|
if (err) {
|
2011-03-28 03:17:52 -07:00
|
|
|
fprintf(stdout, "Socket error\n");
|
2011-03-28 01:55:29 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
void on_accept(oio_handle* server) {
|
2011-04-07 04:51:59 +02:00
|
|
|
peer_t* p = (peer_t*)malloc(sizeof(peer_t));
|
2011-03-30 01:34:56 +02:00
|
|
|
|
2011-04-15 03:32:55 +02:00
|
|
|
if (oio_tcp_handle_accept(server, &p->handle, on_close, (void*)p))
|
|
|
|
FATAL(oio_tcp_handle_accept failed)
|
2011-03-28 01:55:29 -07:00
|
|
|
|
2011-04-07 04:51:59 +02:00
|
|
|
p->buf.base = (char*)&p->read_buffer;
|
2011-03-28 01:55:29 -07:00
|
|
|
|
2011-03-28 03:17:52 -07:00
|
|
|
try_read(p);
|
2011-04-01 00:09:06 +02:00
|
|
|
}
|
2011-03-28 01:55:29 -07:00
|
|
|
|
2011-04-01 00:09:06 +02:00
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
void on_server_close(oio_handle* handle, oio_err err) {
|
2011-04-15 03:32:55 +02:00
|
|
|
ASSERT(handle == &server);
|
|
|
|
ASSERT(!err)
|
2011-03-28 01:55:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-30 22:42:02 -07:00
|
|
|
int echo_start(int port) {
|
2011-04-07 11:02:54 +02:00
|
|
|
struct sockaddr_in addr = oio_ip4_addr("0.0.0.0", port);
|
2011-04-01 00:09:06 +02:00
|
|
|
int r;
|
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
r = oio_tcp_handle_init(&server, on_server_close, NULL);
|
2011-04-07 04:51:59 +02:00
|
|
|
if (r) {
|
|
|
|
/* TODO: Error codes */
|
|
|
|
fprintf(stderr, "Socket creation error\n");
|
|
|
|
return 1;
|
|
|
|
}
|
2011-03-28 01:55:29 -07:00
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
r = oio_bind(&server, (struct sockaddr*) &addr);
|
2011-03-29 10:08:45 -07:00
|
|
|
if (r) {
|
2011-03-30 22:42:02 -07:00
|
|
|
/* TODO: Error codes */
|
2011-03-29 10:08:45 -07:00
|
|
|
fprintf(stderr, "Bind error\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
r = oio_listen(&server, 128, on_accept);
|
2011-03-29 10:08:45 -07:00
|
|
|
if (r) {
|
2011-03-30 22:42:02 -07:00
|
|
|
/* TODO: Error codes */
|
2011-03-29 10:08:45 -07:00
|
|
|
fprintf(stderr, "Listen error\n");
|
|
|
|
return 1;
|
|
|
|
}
|
2011-03-28 01:55:29 -07:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2011-04-01 00:09:06 +02:00
|
|
|
|
2011-04-05 01:43:17 +02:00
|
|
|
|
2011-04-01 00:09:06 +02:00
|
|
|
int echo_stop() {
|
2011-04-07 11:02:54 +02:00
|
|
|
return oio_close(&server);
|
2011-04-05 01:43:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST_IMPL(echo_server) {
|
2011-04-07 11:02:54 +02:00
|
|
|
oio_init();
|
2011-04-05 01:43:17 +02:00
|
|
|
if (echo_start(TEST_PORT))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
fprintf(stderr, "Listening!\n");
|
2011-04-07 11:02:54 +02:00
|
|
|
oio_run();
|
2011-04-05 01:43:17 +02:00
|
|
|
return 0;
|
2011-04-14 11:19:36 -07:00
|
|
|
}
|