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
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
rantlist did not fit into the comments. Hope this helps a little.Edit 0:
Here’s the usual setup with
epoll(7):fcntl(2)withO_NONBLOCK).epoll_data.fdto your socket descriptor for each potential channel (four sockets in your example). Other options are possible withunion epoll_dataif you want to keep more complex structures then just socket descriptors.EPOLLINandEPOLLETto get edge-triggered behavior, i.e. be woken up when input buffer becomes not empty.EPOLLOUTif you getEWOULDBLOCKfrom awrite(2), otherwise do output as usual. Same logic here withEPOLLETto detect output buffer space becoming available.EPOLLRDHUPto detect other side disconnecting cleanly (for abrupt disconnects you need to handleEPIPEerror formwrite(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 getEWOULDBLOCK.EWOULDBLOCKor you don’t have more output data pending (removeEPOLLOUTin 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-1witherrno(3)set toEINPROGRESSand you wait for the socket to become writable as above).