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
Related
What function should I look into to create a socket for my mini-ftp server in C in the stdlib, except recv, send and all system calls that make a socket non-blocking?
There are plenty of guides for this sort of thing, in particular see Beej's Guide to Network Programming for working with Linux. There are similar / equivelant APIs exposed in Windows and other operating systems.
Fundamentally though, if you're using Liunx, you'll be interested in:
socket() to create the socket
connect() / bind() and listen() to connect or listen
send() and recv() to send and receive
If you're interested in non-blocking I/O, then the "Blocking" section will help.
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
I'm writing a server in C ++ for both Windows and Unix systems.
A key feature of this server is that it must be able to receive and send network packets at any time.
Specifically, the server must be able to send data to the client not only in response to their messages, but also be able to send packets to them asynch in push.
I'm having difficulty in implementing a solution that uses the select() function in the scenario described above.
The solution I have currently implemented does not convince me at all and I think it can be implemented with better patterns/solutions.
I currently have a dedicated thread (selector) that performs the select by listening on events in the reading for the server socket (to accept new connections) and for the sockets connected to the server.
This is the main select() loop:
if((sel_res_ = select(nfds_+1, &read_FDs_, NULL, &excep_FDs_, &sel_timeout)) > 0){
if(FD_ISSET(serv_socket, &read_FDs_)){
//we have to handle a newly connection.
...
if(sel_res_ > 1){
//in addition to the newly connection, there is also some other message incoming on client sockets.
...
}
}else{
//we have to handle incoming messages on client sockets
...
}
}
This solution works well for receiving the data and to respond to client requests in synchronous form.
However, the server must also be able to send asynchronous data, and send when necessary, packets in push.
To do this I currently use separate threads that perform directly the send() on the client sockets.
This solution does not convince me, and I would like to centralize the packets receiving and sending on the selector thread.
The main difficulty is that the select() by its nature is blocking and I have no control until a client does not send any packet or the timeout is triggered.
The solution to set a timeout very low does not convince me; I see it as an easy solution that is actually doing active wait, and not only, however, the worst case I would pay the price of the timeout before sending the push packet.
I thought a more 'elegant' solution; I think, will work well, but only for a Unix/Linux platform.
I thought to use an anonymous pipe and insert into the select() read_FDs_ the anonymous pipe read descriptor.
In this way, when a thread wants to send a data in push, it writes something on this pipe, interrupting the select() and returning control to the selector that can then predispose to send the data to the client, without significant loss of time.
I think that this solution, unfortunately, cannot be implemented on Windows because the select() function on that system works only with fds that are actually sockets.
So the question is: Is there some well known solution that can be used to address this kind of scenario (both Linux and Windows)?
You can create a self connected UDP socket, this works equally well on Windows and Linux.
Basically, you create a UDP socket, bind() it to INADDR_LOOPBACK and port 0, and connect() it to itself (with the address taken from getsockname()).
At this point, you can send yourself a single byte message (or something more specific) to wake yourself up.
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.
What are Async Sockets? How are they different from normal sockets (Blocking and Non-Blocking)?
Any pointers in that direction or any links to tutorials will be helpful.
Thanks.
There are three ways to communicate with sockets in async way:
Open regular socket, but do not read from it (because read() blocks) until you know there it something to be read. You can use select() or poll() to check whether there are data to read from socket(s), and if there is something, read it, as read() won't block.
Switch socket to non-blocking I/O, by setting O_NONBLOCK flag with fcntl() function. In this case read() won't block.
Set socket's O_ASYNC flag using FIOASYNC option of ioctl() (see man 7 socket for details). In this case you will receive SIGIO signal when there is something to read from socket.
Third approach is async socket.
Comparison of the following five different models for I/O in UNIX Network Programming: The sockets networking API would be helpful:
Blocking
Nonblocking
I/O multiplexing
Signal-driven I/O
Asynchronous I/O
If a server uses a synchronous socket, while it is waiting for data from the client, its main thread is blocked, so the server won't be doing anything... that is bad if you have multiple clients connecting. In an asynchronous socket, you CAN do other stuff while waiting for the client to send data to you, so now you CAN have multiple clients connecting to you
Synchronous uses a function like receive() which blocks until it gets a message
Asynchronous has beginReceive() endReceive() or similar functions. It uses callbacks, when a message is received, the callback is invoked