Reputation: 81
I have an application with multiple threads, one thread is creating 4 tcp connections, then this thread creates another thread that will handle the receive function for these 4 connections using poll or anything else, and the original thread (the first one) start sending messages to these 4 connections(round-robin). it's like below pseudo code,
main()
{
pthread_create( &thread1, NULL, sending_thread, (void*) args);
}
void *sending_thread( void *ptr )
{
int i=0;
int *connections;
connections = create_connections();
pthread_create( &thread1, NULL, receiving_thread, (void*)&connections);
while(1) {
send(connections[i], "test");
i++;
if (i > 3)
i=0;
}
}
void *receiving_thread( void *ptr )
{
char *msg;
msg = receive(connections[i]);
save_received_msg_to_disk(msg);
}
My question is How can I check my connections and bring up the disconnected one? for example, let's say connection1 went down, do I need to create another connection with the same fd, which is connection[1] in this case? or is there other ways to handle this case?
Environment is C/pthread in Linux
Upvotes: 2
Views: 2144
Reputation: 84239
Here are some points based on your code and comments.
epoll(7)
to detect saturated connections and be notified when they are available again then starve others.I know this doesn't answer your question directly, but my rant list did not fit into the comments. Hope this helps a little.
Here's the usual setup with epoll(7)
:
fcntl(2)
with O_NONBLOCK
).epoll_data.fd
to your socket descriptor for each potential channel (four sockets in your example). Other options are possible with union epoll_data
if you want to keep more complex structures then just socket descriptors. EPOLLIN
and EPOLLET
to get edge-triggered behavior, i.e. be woken up when input buffer becomes not empty.EPOLLOUT
if you get EWOULDBLOCK
from a write(2)
, otherwise do output as usual. Same logic here with EPOLLET
to detect output buffer space becoming available.EPOLLRDHUP
to detect other side disconnecting cleanly (for abrupt disconnects you need to handle EPIPE
error form write(2)
).epoll_wait(2)
gives you back number of events to iterate through. Do separate checks for input (events & EPOLLIN
) and output (events & EPOLLOUT
).data.fd
(or otherwise associated socket) until you get EWOULDBLOCK
.EWOULDBLOCK
or you don't have more output data pending (remove EPOLLOUT
in that case).It looks like a lot, but is pretty simple once you get a hang of it.
You can also do non-blocking connect(2)
, which is probably a good idea if you ever want to re-establish broken streams without hurting others that are still chugging along (connect(2)
returns -1
with errno(3)
set to EINPROGRESS
and you wait for the socket to become writable as above).
Upvotes: 2