Commit 805c6154 authored by dguyot's avatar dguyot
Browse files

Initial dev commit

parents
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <assert.h>
#include <endian.h>
#include <uv.h>
#include <string.h>
#include <string>
#include <iostream>
//debug
#include <unistd.h>
#define ACTION_CMD 0
#define ACTION_GET 1
#define ACTION_PUT 2
#define ACTION_TIME 3
#define ACTION_INFO 4
#define ACTION_ERROR 5
#define ACTION_KILL 6
//debug
#define PL printf("%s : %d\n",__FUNCTION__,__LINE__);
#define PVA(X) printf("%p at %p\n", X, &X);
#define PH(X) fprintf(stderr,"%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\n",X.uint64[0],X.uint64[1],X.uint64[2],X.uint64[3],X.uint64[4],X.uint64[5],X.uint64[6],X.uint64[7]);
using namespace::std;
string dataline(" data from client");
union int2char{
uint64_t uint64[8];
char char8[64];
};
struct Client{
int r;
struct sockaddr_in dest;
uv_loop_t *loop = NULL;
uv_connect_t *con = NULL;
uv_tcp_t *tcp = NULL;
uv_stream_t *stream = NULL;
int2char uheader;
uv_buf_t header;
uv_buf_t cmd;
uv_buf_t data;
uv_write_t wr;
// Client(string interface){
Client(uv_loop_t* l){
PL
loop = l;
tcp = reinterpret_cast<uv_tcp_t*>(malloc(sizeof(uv_tcp_t)));
r = uv_tcp_init(loop, tcp);
assert(r == 0);
stream = reinterpret_cast<uv_stream_t*>(tcp);
con = static_cast<uv_connect_t*>(malloc(sizeof(uv_connect_t)));
header.base = uheader.char8;
header.len = sizeof(uheader);
tcp->data = this;
PL
}
~Client(){
PL
free(tcp);
free(con);
PL
}
void connect(string interface){
//parse the interface string to extract ip and port
string ip = interface.substr(0,interface.find(':'));
int port = stoi(interface.substr(interface.find(':') + 1,interface.size()));
r = uv_ip4_addr(ip.c_str(), port, &dest);
assert(r == 0);
//r = uv_tcp_connect(con, tcp, (const struct sockaddr*)&dest, con_cb);
r = uv_tcp_connect(con, tcp, (const struct sockaddr*)&dest,
[](uv_connect_t* c, int status){
PL
Client* C = static_cast<Client*>(c->handle->data);
C->send_header(ACTION_CMD);
PL
}
);
assert(r == 0);
r = uv_tcp_nodelay(tcp,1);
assert(r == 0);
}
void send_header(uint64_t act){
PL
int r;
action() = act;
switch (act){
case ACTION_CMD:
hheader() = 0;
r = uv_write(&wr, stream, &header, 1,
[](uv_write_t* wr, int status){
PL
Client* C = static_cast<Client*>(wr->handle->data);
C->recv_header_cmd();
PL
}
);
assert(r == 0);
break;
case ACTION_GET:
hheader() = 0;
r = uv_write(&wr, stream, &header, 1,
[](uv_write_t* wr, int status){
PL
Client* C = static_cast<Client*>(wr->handle->data);
C->recv_header_data();
PL
}
);
assert(r == 0);
break;
case ACTION_PUT:
size() = dataline.size();
ret() = 0;
rtime() = 0;
utime() = 0;
stime() = 0;
hdata() = 0;
hheader() = 0;
r = uv_write(&wr, stream, &header, 1,
[](uv_write_t* wr, int status){
PL
Client* C = static_cast<Client*>(wr->handle->data);
C->send_data();
PL
}
);
assert(r == 0);
break;
case ACTION_TIME:
hheader() = 0;
break;
case ACTION_INFO:
hheader() = 0;
break;
case ACTION_KILL:
hheader() = 0;
break;
case ACTION_ERROR:
hheader() = 0;
break;
}
PL
}
void recv_header_cmd(){
PL
int r;
r = uv_read_start(stream,
[](uv_handle_t* handle, size_t size, uv_buf_t* buf){*buf = ((Client*)(handle->data))->header;},
[](uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf){
PL
Client* C = static_cast<Client*>(stream->data);
//all reads are done?
if (nread == (ssize_t)buf->len){
uv_read_stop(stream);
PH(C->uheader)
C->recv_cmd();
}
else if (nread < 0){
C->on_bad_read(nread);
}
PL
}
);
assert(r == 0);
PL
}
void recv_cmd(){
PL
int r;
cmd.len = size();
cmd.base = static_cast<char*>(malloc(size()));
r = uv_read_start(stream,
[](uv_handle_t* handle, size_t size, uv_buf_t* buf){*buf = ((Client*)(handle->data))->cmd;},
[](uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf){
PL
Client* C = static_cast<Client*>(stream->data);
if (nread == (ssize_t)buf->len){
uv_read_stop(stream);
for(int i = 0; i < nread; i++){
fprintf(stderr, "%c", (buf->base)[i]);
}
fprintf(stderr, "\n");
free(buf->base);
C->send_header(ACTION_GET);
}
else if (nread < 0){
C->on_bad_read(nread);
}
PL
}
);
assert(r == 0);
PL
}
void recv_header_data(){
PL
int r;
r = uv_read_start(stream,
[](uv_handle_t* handle, size_t size, uv_buf_t* buf){*buf = ((Client*)(handle->data))->header;},
[](uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf){
PL
Client* C = static_cast<Client*>(stream->data);
if (nread == (ssize_t)buf->len){
uv_read_stop(stream);
PH(C->uheader)
C->recv_data();
}
else if (nread < 0){
C->on_bad_read(nread);
}
PL
}
);
assert(r == 0);
PL
}
void recv_data(){
PL
int r;
data.len = size();
data.base = static_cast<char*>(malloc(size()));
r = uv_read_start(stream,
[](uv_handle_t* handle, size_t size, uv_buf_t* buf){*buf = ((Client*)(handle->data))->data;},
[](uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf){
PL
Client* C = static_cast<Client*>(stream->data);
if (nread == (ssize_t)buf->len){
uv_read_stop(stream);
for(int i = 0; i < nread; i++){
fprintf(stderr, "%c", (buf->base)[i]);
}
fprintf(stderr, "\n");
free(buf->base);
C->send_header(ACTION_PUT);
}
else if (nread < 0){
C->on_bad_read(nread);
}
PL
}
);
assert(r == 0);
PL
}
void send_data(){
PL
int r;
data.len = dataline.size();
data.base = const_cast<char*>(dataline.c_str());
r = uv_write(&wr, stream, &data, 1,
[](uv_write_t* wr, int status){
PL
Client* C = static_cast<Client*>(wr->handle->data);
C->send_header(ACTION_GET);
PL
}
);
assert(r == 0);
PL
}
void on_bad_read(ssize_t nread){
PL
//on disconnect
if (nread == UV_EOF || nread == UV_ECONNRESET){
close();
}
//an error occured
else {
cerr << uv_strerror(nread) << endl;
}
PL
}
void close() {
PL
uv_handle_t* handle = reinterpret_cast<uv_handle_t*>(tcp);
uv_close(handle,
[](uv_handle_t* handle){
PL
Client* C = static_cast<Client*>(handle->data);
delete(C);
PL
}
);
PL
}
uint64_t& action(){return uheader.uint64[0];}
uint64_t& size(){return uheader.uint64[1];}
uint64_t& ret(){return uheader.uint64[2];}
uint64_t& rtime(){return uheader.uint64[3];}
uint64_t& utime(){return uheader.uint64[4];}
uint64_t& stime(){return uheader.uint64[5];}
uint64_t& hdata(){return uheader.uint64[6];}
uint64_t& hheader(){return uheader.uint64[7];}
};
int main(int argc, char** argv){
PL
int r;
uv_loop_t* loop = uv_default_loop();
Client* C = new Client(loop);
C->connect("134.214.33.18:8000");
r = uv_run(loop, UV_RUN_DEFAULT);
assert(r == 0);
uv_loop_close(loop);
PL
return(0);
}
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <uv.h>
#include <assert.h>
#include <unordered_map>
#include <string>
#include <iostream>
#include <string.h>
#define ACTION_CMD 0
#define ACTION_GET 1
#define ACTION_PUT 2
#define ACTION_TIME 3
#define ACTION_INFO 4
#define ACTION_ERROR 5
#define ACTION_KILL 6
//debug
#define PL fprintf(stderr,"%s : %d\n",__FUNCTION__,__LINE__);
#define PVA(X) fprintf(stderr,"(%s) : %p at address %p\n", #X, X, &(X));
#define PH(X) fprintf(stderr,"%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\n",X.uint64[0],X.uint64[1],X.uint64[2],X.uint64[3],X.uint64[4],X.uint64[5],X.uint64[6],X.uint64[7]);
using namespace::std;
string cmdline("gruttamutacommande");
string dataline(" data from server");
union int2char{
uint64_t uint64[8];
char char8[64];
};
struct Server;
struct Service{
uv_stream_t* server;
uv_tcp_t* tcp;
uv_stream_t* stream;
uv_write_t wr;
int2char uheader;
uv_buf_t header;
uv_buf_t cmd;
uv_buf_t sdata;
uv_buf_t rdata;
Service(uv_stream_t* s){
PL
int r;
server = s;
tcp = static_cast<uv_tcp_t*>(malloc(sizeof(uv_tcp_t)));
assert(tcp != NULL);
r = uv_tcp_init(server->loop, tcp);
assert(r == 0);
uv_tcp_nodelay(tcp,1);
stream = reinterpret_cast<uv_stream_t*>(tcp);
r = uv_accept(server, stream);
assert(r == 0);
header.base = uheader.char8;
header.len = sizeof(uheader);
tcp->data = this;
PL
}
~Service(){
PL
free(tcp);
PL
}
void start(){
PL
recv_header();
PL
}
void recv_header(){
PL
int r;
r = uv_read_start(stream,
[](uv_handle_t* tcp, size_t size, uv_buf_t* buf){*buf = (static_cast<Service*>(tcp->data))->header;},
[](uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf){
PL
Service* S = reinterpret_cast<Service*>(stream->data);
//is read complete?
if (nread == (ssize_t)buf->len){
uv_read_stop(stream);
PH(S->uheader)
switch (S->action()){
case ACTION_CMD:
S->send_header_cmd();
break;
case ACTION_GET:
S->send_header_data();
break;
case ACTION_PUT:
S->recv_data();
break;
case ACTION_TIME:
break;
case ACTION_INFO:
break;
case ACTION_KILL:
break;
case ACTION_ERROR:
break;
}
}
else if (nread < 0){
S->on_bad_read(nread);
}
PL
}
);
assert(r == 0);
PL
}
void send_header_cmd(){
PL
int r;
size() = cmdline.size();
r = uv_write(&wr, stream, &header, 1,
[](uv_write_t* wr, int status){
PL
Service* S = reinterpret_cast<Service*>(wr->handle->data);
S->send_cmd();
PL
}
);
assert(r == 0);
PL
}
void send_cmd(){
PL
int r;
cmd.len = cmdline.size();
cmd.base = const_cast<char*>(cmdline.c_str());
r = uv_write(&wr, stream, &cmd, 1,
[](uv_write_t* wr, int status){
PL
Service* S = reinterpret_cast<Service*>(wr->handle->data);
S->recv_header();
PL
}
);
assert(r == 0);
PL
}
void send_header_data(){
PL
int r;
size() = dataline.size();
r = uv_write(&wr, stream, &header, 1,
[](uv_write_t* wr, int status){
PL
Service* S = reinterpret_cast<Service*>(wr->handle->data);
S->send_data();
PL
}
);
assert(r == 0);
PL
}
void send_data(){
PL
int r;
sdata.len = dataline.size();
sdata.base = const_cast<char*>(dataline.c_str());
r = uv_write(&wr, stream, &sdata, 1,
[](uv_write_t* wr, int status){
PL
Service* S = reinterpret_cast<Service*>(wr->handle->data);
S->recv_header();
PL
}
);
assert(r == 0);
PL
}
void recv_data(){
PL
int r;
rdata.len = size();
cerr << size() << endl;
rdata.base = static_cast<char*>(malloc(size()));
r = uv_read_start(stream,
[](uv_handle_t* tcp, size_t size, uv_buf_t* buf){*buf = (static_cast<Service*>(tcp->data))->rdata;},
[](uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf){
PL
Service* S = reinterpret_cast<Service*>(stream->data);
//is read complete?
if (nread == (ssize_t)buf->len){
uv_read_stop(stream);
for(int i = 0; i < nread; i++){
fprintf(stderr, "%c", (buf->base)[i]);
}
fprintf(stderr, "\n");
free(buf->base);
S->recv_header();
}
else if (nread < 0){
S->on_bad_read(nread);
}
PL
}
);
assert(r == 0);
}
void on_bad_read(ssize_t nread){
PL
//disconnection
if (nread == UV_EOF || nread == UV_ECONNRESET) {
close();
}
//error handling
else {
cerr << uv_strerror(nread) << endl;
}
PL
}
void close(){
PL
uv_handle_t* handle = reinterpret_cast<uv_handle_t*>(tcp);
uv_close(handle,
[](uv_handle_t* handle){
PL
Service* S = reinterpret_cast<Service*>(handle->data);
delete(S);
PL
}
);
uv_close(reinterpret_cast<uv_handle_t*>(static_cast<Service*>(handle->data)->server), NULL);
PL
}
//reference accessors for the header
uint64_t& action(){return uheader.uint64[0];}
uint64_t& size(){return uheader.uint64[1];}
uint64_t& ret(){return uheader.uint64[2];}
uint64_t& rtime(){return uheader.uint64[3];}
uint64_t& utime(){return uheader.uint64[4];}
uint64_t& stime(){return uheader.uint64[5];}
uint64_t& hdata(){return uheader.uint64[6];}
uint64_t& hheader(){return uheader.uint64[7];}