I am working on a project which requires monitoring on a socket. I know how to do the busy waiting using while-loop to keep reading incoming data if there is one.
Is there a way to setup a callback function so that whenever there is data on the I/O, it will read the data and call my callback function?
There are more-or-less supported socket calls: poll(), select(), epoll() which don't provide a callback, but are better than simple read(). On a fully compliant POSIX system, there is posix_aio. For cross platform support, there are several libraries (not part of standard C library) that provide what you want, like libuv, libevent, etc. – srdjan.veljkovic
Related
Is there any way to associate callback functions with sockets in Linux?
For example,
After connect(s, (struct sockaddr *)peeraddr, sizeof(*peeraddr)) function has connected client with server, is there a way to associate a function- afterRecv with socket- s such that after recv function has read some data from socket, afterRecv gets called?
My socket is of blocking type. The reason behind this kind of requirement is, I am working with a OpenSSL which does many send/recv calls on socket during handshake period internally. If I modify OpenSSL then it would be quite cumbersome to modify each and every recv. So I was thinking if I can add callback that would make my job easy.
The flow should be:
Socket connection logic
Recv function
After recv has read data, afterRecv gets called as a callback on recv
Some event libraries implement such callback hooks:
libev
libevent
and all graphical or HTTP server libraries (e.g. Gtk/Glib, Qt, LibOnion, ...) provide (or use) such event libraries (around a multiplexing syscall like poll(2) etc).
Both Glib (from GTK) and QtCore (from Qt) are event libraries usable without any GUI
Read also about the C10K problem
I am writing a cross-platform library which emulates sockets behaviour, having additional functionality in the between (App->mylib->sockets).
I want it to be the most transparent possible for the programmer, so primitives like select and poll must work accordingly with this lib.
The problem is when data becomes available (for instance) in the real socket, it will have to go through a lot of processing, so if select points to the real socket fd, app will be blocked a lot of time. I want the select/poll to unblock only when data is ready to be consumed (after my lib has done all the processing).
So I came across this eventfd which allows me to do exactly what I want, i.e. to manipule select/poll behaviour on a given fd.
Since I am much more familiarized with Linux environment, I don't know what is the windows equivalent of eventfd. Tried to search but got no luck.
Note:
Other approach would be to use another socket connected with the interface, but that seems to be so much overhead. To make a system call with all data just because windows doesn't have (appears so) this functionality.
Or I could just implement my own select, reinventing the wheel. =/
There is none. eventfd is a Linux-specific feature -- it's not even available on other UNIXy operating systems, such as BSD and Mac OS X.
Yes, but it's ridiculous. You can make a Layered Service Provider (globally installed...) that fiddles with the system's network stack. You get to implement all the WinSock2 functions yourself, and forward most of them to the underlying TCP. This is often used by firewalls or antivirus programs to insert themselves into the stack and see what's going on.
In your case, you'd want to use an ioctl to turn on "special" behaviour for your application. Whenever the app tries to create a socket, it gets forwarded to your function, which in turn opens a real TCP socket (say). Instead of returning that HANDLE though, you use a WinSock function to create ask for a dummy handle from the kernel, and give that to the application instead. You do your stuff in a thread. Then, when the app calls WinSock functions on the dummy handle, they end up in your implementation of read, select, etc. You can decouple select notifications on the dummy handle from those on the actual handle. This lets you do things like, for example, transparently give an app a socket that wraps data each way in encryption, indistinguishably from the original socket. (Almost indistinguishably! You can call some LSP APIs on a handle to find out if there's actually and underlying handle you weren't given.)
Pretty heavy-weight, and monstrous in some ways. But, it's there... Hope that's a useful overview.
I'm working on a basic UDP socket file transfer server/client setup, using go-back-n windowing, and unfortunately am stuck doing it using Winsock due to assignment constraints.
Normally in order to manage timeouts on outstanding packets I would just use signal() but am unsure as to how/if this actually really works on Windows, and if this is actually the best solution. Is there some best way to handle these sorts of socket timeouts? Or am I best just managing timeouts with select()?
If your application has a "main()" function then using select() to manage timeouts is the most convenient as it has the advantage that it uses only socket api calls, so the code should work on any platform supporting a bsd style socket api and doesn't require a windows message loop.
If you are writing a window GUI style application - usually with a WinMain() entry point and a message loop, then WSAAsyncSelect() on a socket handle will get read (and write) ready notification messages posted to a HWND - SetTimer likewise posts periodic WM_TIMER notifications, and GetTickCount can be used to detect which socket has been idle too long.
I'd like to know whether something like this has been done before:
I've recently started work on a networking library in C. The library maintains a set of sockets, each of which is associated with two FIFO byte streams, input and output.
A developer using the library is expected to register some callbacks, consisting of a recognizer function and a handler function. If new data arrives on a socket (i.e. the input stream), every recognizer is called. If one of the recognizers finds a matching portion of data, its associated handler is called, consuming the data and possibly queuing new data on the socket's output stream, scheduled to be transmitted later on.
Here's an example to make clear how the library is used:
// create client socket
client = nc_create(NC_CLIENT);
// register some callback functions that you'll have to supply yourself
nc_register_callback(client, &is_login, &on_login);
nc_register_callback(client, &is_password, &on_password);
// connect to server
nc_dial(client, "www.google.com", "23");
// start main loop (we might as well have more than one connection here)
nc_talk();
To me, this is the most obvious way to write a general purpose networking library in C. I did some research using Google, but I wasn't able to find something similar written in C. But it's hard to believe that I'm the first one that implements this approach.
Are there other data-driven general purpose C networking libraries like this out there?
Would you use them?
Here's a few libraries that provides similar APIs, (at various levels, e.g. libevent provides a general callback driven API for socket/file descriptors)
libesmtp (example)
libevent
libcurl
The Sun/OncRPC APIs have a similar style, in that the library does the heavy lifting for you, dispatching requests to the proper callback handlers.
The Java netty and mina libraries works in a similar manner, although more object oriented.
I've seached such question in google and got different answers.I cann't determine whether posix aio in linux 2.6 support socket file descriptor or not.
if it support tcp socket,does the aiocb.aio_offset=0 relative to the first byte readed from the tcp socket fd?
if it doesn't,does any asynchronous io library in linux support socket fd?
A comment above states that aio does not support sockets. You ask for possible alternatives.
The obvious ones are:
use an event driven programming model, either produced by hand using poll(2) or what have you or via a library like Niels Provos' "libevent"
use threads
I generally prefer the event driven way of doing things, and generally use libevent, which is documented here: http://libevent.org/
Bear in mind, however, that event driven programming is rather heavily different from what you may be used to in program organization. Threads are conceptually similar, although often less efficient when handling large numbers of sockets.