rxi / dyad Goto Github PK
View Code? Open in Web Editor NEWAsynchronous networking for C
License: MIT License
Asynchronous networking for C
License: MIT License
I modified the example echoserv.c a bit like this to get ip address:
...
static void onAccept(dyad_Event *e) {
printf("IP:%s\n",dyad_getAddress(e->remote));
dyad_addListener(e->remote, DYAD_EVENT_DATA, onData, NULL);
dyad_writef(e->remote, "echo server\r\n");
}
...
int main(void) {
dyad_Stream *s;
dyad_init();
s = dyad_newStream();
dyad_addListener(s, DYAD_EVENT_ERROR, onError, NULL);
dyad_addListener(s, DYAD_EVENT_ACCEPT, onAccept, NULL);
dyad_listen(s, 8000);
printf("IP:%s\n",dyad_getAddress(s));
while (dyad_getStreamCount() > 0) {
dyad_update();
}
return 0;
}
Finally I got the host ip address 0.0.0.0 which looks like invalid but the remote address is valid. The communication works well.
Is it a bug concerned with OS or my incorrect practice of API?
Hey, I am trying to convert this to c++ for a project I am on. When i change the dyad.c file to dyad.cpp the conversion requires me to cast all of the reallocs instantly.
For instance: data = (char)dyad_realloc(_data, *capacity * memsz);
instead of: *data = dyad_realloc(_data, *capacity * memsz);
This causes the connection for the ircbot to fail and return a bad request. Do you know of a way to fix this?
Just a nitpick, dyad_setSocketNonBlocking does this:
fcntl(stream->sockfd, F_SETFL, opt ? O_NONBLOCK : ~O_NONBLOCK);
Which blows away any other flags. It should be:
flags = fcntl(stream->sockfd, F_GETFL);
fcntl(stream->sockfd, F_SETFL, opt ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK));
Listening sockets are created with the AF_UNSPEC family flag, this causes an IPv6 socket to be returned on Windows systems supporting them. As Windows has completely separate networking stacks for IPv4 and IPv6, the end result is that such sockets won't accept IPv4 connections, including local connections via loopback (127.0.0.1, or localhost
which maps to the same).
The workaround I came up with was to pass in AF_INET
for the socket family in dyad_listenEx()
:
/* Get addrinfo */
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
sprintf(buf, "%d", port);
err = getaddrinfo(host, buf, &hints, &ai);
However, this leads to the opposite problem: IPv6 clients can't connect. Would there a way to support both protocols for listening sockets?
When dyad_shutdown()
is called, all outstanding streams have dyad_close()
called on them. This prevents any data recently written to the stream--for example, a message indicating the session is ending--not to be received on the other end. It would be nicer if instead, shutdown could flush write buffers before closing the streams.
This could be optional, as the current behavior may be preferable in some circumstances.
Sorry for this simple question, but I do not understand how to reconnect after a failure.
I tried a few combinations of dyad_end
/ dyad_update
but it always fails.
(see example here here )
The only way that seems to work is to create a new stream and reset the callback functions.
Is this the correct method?
`
#define vec_push(v, val)
( vec_expand(vec_unpack(v)),
(v)->data[(v)->length++] = (val) )
void dyad_addListener(
dyad_Stream *stream, int event, dyad_Callback callback, void *udata
) {
Listener listener;
listener.event = event;
listener.callback = callback;
listener.udata = udata;
vec_push(&stream->listeners, listener);
}
the listener will be free
how can (v)->data[(v)->length++] = (val) for c
static dyad_Event createEvent(int type) {
dyad_Event e;
memset(&e, 0, sizeof(e));
e.type = type;
return e;
}
'e' has been freed when this func returned
any memory cordump problem ?
Seems like httpserv
and httpserv2
examples did not works properly after successful compilation with cygwin/mingw gcc, at least in my windows environment.
Thehttpget
works as expected, but httpserv
output only a server listening on port 8000
and then have no ractions on external requests (brandmauer switched off). I checked different ports, additional logs in events listeners - seems like only onListen
catched.
There some compiled binaries for test.
VirusTotal complains a bit about binaries compiled with mingw-gcc, so I put only cygwin ones, results similar.
system: W7 x64
cygwin-gcc:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-pc-cygwin/4.8.2/lto-wrapper.exe
Target: i686-pc-cygwin
Configured with: /cygdrive/i/szsz/tmpp/gcc4/gcc-4.8.2-2/src/gcc-4.8.2/configure --srcdir=/cygdrive/i/szsz/tmpp/gcc4/gcc-4.8.2-2/src/gcc-4.8.
2 --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/libexec --datadir=/usr/share --localstatedir=/var
--sysconfdir=/etc --libdir=/usr/lib --datarootdir=/usr/share --docdir=/usr/share/doc/gcc --htmldir=/usr/share/doc/gcc/html -C --build=i686-
pc-cygwin --host=i686-pc-cygwin --target=i686-pc-cygwin --without-libiconv-prefix --without-libintl-prefix --enable-shared --enable-shared-l
ibgcc --enable-static --enable-version-specific-runtime-libs --enable-bootstrap --disable-__cxa_atexit --with-dwarf2 --with-arch=i686 --with
-tune=generic --disable-sjlj-exceptions --enable-languages=ada,c,c++,fortran,java,lto,objc,obj-c++ --enable-graphite --enable-threads=posix
--enable-libatomic --enable-libgomp --disable-libitm --enable-libquadmath --enable-libquadmath-support --enable-libssp --enable-libada --ena
ble-libjava --enable-libgcj-sublibs --disable-java-awt --disable-symvers --with-ecj-jar=/usr/share/java/ecj.jar --with-gnu-ld --with-gnu-as
--with-cloog-include=/usr/include/cloog-isl --without-libiconv-prefix --without-libintl-prefix --with-system-zlib --libexecdir=/usr/lib
Thread model: posix
gcc version 4.8.2 (GCC)
I hope this particular problem of my environment. Under linux everything works like a charm.
I am trying to send a message each 100 ms but client accepts only one message per second. I checked my code. There is no sleep code around. What could be the reason?
Thank you.
This would be helpful for many, not just me.
I am new to dyad.c and i just created a project with it and when attempting to compile i got these errors.
************* Compiler Log ******************
Compiler: Default compiler
Building Makefile: "C:\Users\deel\Documents\CPP\dyad\Makefile.win"
Executing make...
make.exe -f "C:\Users\deel\Documents\CPP\dyad\Makefile.win" all
g++.exe -c dyad.c -o dyad.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"C:/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"C:/Dev-Cpp/include/c++/3.4.2" -I"C:/Dev-Cpp/include" -lwsock32
dyad.c: In function void vec_expand(char**, int*, int*, int)': dyad.c:111: error: invalid conversion from
void_' to `char_'
dyad.c: In function void select_grow(SelectSet*)': dyad.c:205: error: invalid conversion from
void_' to `fd_set_'
dyad.c: In function void stream_initAddress(dyad_Stream*)': dyad.c:462: error: invalid conversion from
void_' to `char_'
dyad.c:467: error: invalid conversion from void*' to
char*'
dyad.c: In function void dyad_update()': dyad.c:720: warning: converting to
long int' from `double'
dyad.c:721: warning: converting to long int' from
double'
dyad.c: In function dyad_Stream* dyad_newStream()': dyad.c:871: error: invalid conversion from
void_' to `dyad_Stream_'
dyad.c: In function void dyad_write(dyad_Stream*, const void*, int)': dyad.c:1040: error: invalid conversion from
const void_' to `const char_'
make.exe: *** [dyad.o] Error 1
Execution terminated
Hi. Is it possible to use Python sockets to contact with C side that uses dyad?
I saw that select_max is 3 fd in the loop only? Is that faster than epoll?
I wrote a server and a client in local by example, but client always show "could not connect to server".
As an asynchronous networking lib, it is necessary to have a timer event and related callbacks. Could you please add it?
When calling "dyad_listen(serv, )", it does not accept local connections. As a workaround, I have used "dyad_listenEx(serv, "0.0.0.0", , 511)".
Hi!
This project is really simple and works very well!
I would suggest to include support for unix domain socket (AF_UNIX).
Regards!
I would like my server to send a message to all the open connections.
In order to do so I think I need to loop on active streams. How can this be done?
Thanks!
ps: sorry for all these issues, I don't know how else to contact you.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.