How to send data immediately in epoll ET mode when connect established - epoll

My server needs to send data when client connects to it. I am using Epoll ET mode.
But how to do it? Could any one give me a simple example for me?

Assuming you are listening on your socket (socket, bind, listen), and have added it's descriptor to epoll (epoll_create and epoll_ctl), then epoll_wait will tell you when there is a new connection to accept.
First you accept the connection (sockfd is descriptor of socket you're listening on, efd is epoll instance) and add it to your epoll instance:
int connfd = accept4(sockfd, NULL, 0, SOCK_NONBLOCK);
struct epoll_event ev;
ev.events = EPOLLOUT | EPOLLET;
ev.data.fd = connfd;
epoll_ctl(efd, EPOLL_CTL_ADD, connfd, &ev)
Then you go back to your main loop and call epoll_wait again. It will tell you when the socket is ready for writing, and you just happily write or sendfile away.
Add lots of error checking, and probably TCP_CORK and you're done. There's a working example on github.com/grahamking/netshare/.
I hope this gives you enough information to get started.

Related

what's the exactly meaning of EV_TIMEOUT in libevent?

In Programming with Libevent book, it says:
EV_TIMEOUT
This flag indicates an event that becomes active after a timeout
elapses.
AFAIK, an event associate with socket fd will become active when network IO event is ready, which is notified by select/epoll/poll/kqueue.
If EV_TIMEOUT make an event active, while the socket fd is not ready, will event_base do the callback ?
Or the socket fd is ready, while EV_TIMEOUT is not, will event_base do the callback ?
Oh, I understand.
void (*event_callback_fn)(evutil_socket_t, short, void *);
The short flag will tell callback what happened exactly.
When timeout, short & EV_TIMEOUT == true, when socket is ready, short & (EV_READ | EV_WRITE) == true.

How To Disable Nagle on iOS POSIX Socket

I'll start by saying that I definitely want to disable Nagle's Algorithm. The application that I am testing for is a real time P2P app in which packets are small and extremely time sensitive. This test also serves to compare UDP and TCP for possible networking solutions.
I am able to open the TCP socket and send messages back and forth, but I have not been able to disable Nagle's Algorithm. I have tried:
static const int yes = 1;
if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes))) {
fprintf(stderr, "Error setting tcp nodelay\n");
return -2;
}
on both the listening and connecting sockets. This does not fail. I also elevated the priority of the receiving thread to DISPATCH_QUEUE_PRIORITY_HIGH.
The test I am running starts with a packet that contains "start", followed by numerous packets that contain "data" and one final packet containing "stop". These packets are almost always combined into one or few packets, such as:
Received Peer Message: startdatadatadatadatadatadatastop
or
Received Peer Message: startdatadatadata
Received Peer Message: datadatadatastop
Is there a difference in the way that TCP_NODELAY is set on iOS? I was able to set it on Linux with the above code successfully.

libevent : whether event can be triggered if the related socket is closed by local program

if I add an event for a connection socket which is returned by accept(), as below
event_set(&conn_ev, connfd, EV_READ|EV_PERSIST, on_recv, NULL);
event_base_set(base, &conn_ev);
event_add(&conn_ev, NULL);
if at sometime, the local program(not the peer) closes the socket, will the conn_ev be triggered?
if so, how to detect whether whether the event is due to the closing of the socket?
is it recv(connfd,..) returns -1 and errno is set EBAD or any other cases?
thanks!
All sockets are marked as readable if the socket is nicely closed by the other end, with read returning zero. When an error is received they are marked either read- or write-able, with read or write returning -1.
See e.g. the socket(7) manual page for a table of states.

erlang:is_port/1 and sockets

I was reading more about erlang:is_port/1 so I decided to test it with several values.
I saw that with normal sockets it replies true if the socket is up and false otherwise (i.e. socket is down).
Can is_port/1 be used also with ssl sockets? I tried but it always returns false.
If you refer to a SSL Socket as the returned value from (for example) ssl:connect/2,3, then the answer is "no". The SSL Sockets in the context of the SSL application are of a sslsocket() type, which, according to the documentation are opaque to the user and definitely not a port. Specifically, they are records:
%% Looks like it does for backwards compatibility reasons
-record(sslsocket, {fd = nil, pid = nil}).

epoll behavior when writing to a file descriptor

I'm using epoll to write large messages to a server using HTTP protocol. The fds are all set to non-blocking and I'm using edge-triggered events. I know for EPOLLIN I need to loop over reading the fd until EAGAIN is returned. For writing I am unsure if I should keep looping once I get EAGAIN or should I wait for epoll to notify when the fd is available for read again.
For instance, I am writing a 20K message, and on the first ::write attempt the amount of data sent = 13K. The next attempt to write returns a retVal = -1 and errno = EAGAIN.
At this point should I continue looping in a while(1) until I can write the data or should I wait for epoll to invoke my call back when the FD is ready for writing again. My understanding is that since the fd is registered for writing, epoll should notify me when the FD is ready for writing again. But that doesn't seem to be happening in my program.
Do I need to set a special flag or modify the FD to get the notification?
At this point should I continue looping in a while(1) until I can write the data
No!
or should I wait for epoll to invoke my call back when the FD is ready for writing again.
Yes, you should (but what callback? epoll_wait doesn't have a callback mechanism, it just returns)
My understanding is that since the fd is registered for writing, epoll should notify me when the FD is ready for writing again. But that doesn't seem to be happening in my program.
If the FD is registered with EPOLLOUT or EPOLLIN | EPOLLOUT, it should indeed. Could you provide a small example demonstrating the problem?

Resources