1

I'm trying to create asynchronous high performance UDP client. I'm implementing UDP tracker protocol.

Lets say I have 1000 torrent hashes. I need to make 1000/74 ~= 14 UDP requests, assuming that UDP tracker don't have any limits. UDP Tracker protocol supports up to 74 hashes per request via UDP protocol, so i need to create 14 UDP sockets.

I need to use epoll, not poll, select, libevent, libev or libuv.

Every epoll UDP example I find is for server, not client.

I'm having troubles with understanding application logic.

First, i need to create 14 sockets:

#define MAX_CLIENTS 14
int fd[MAX_CLIENTS];

for (i = 0; i < MAX_CLIENTS; i++) {
  if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
    perror("socket");
    exit(EXIT_FAILURE);
  }

  setnonblock(fd[i]); 
}

Then

int efd = epoll_create(MAX_EVENTS);

Now I need to send data via sendto for each of this socket, and receive results via epoll. How can I do that ?

I don't need someone to write code for me, I just want to understand epoll logic better.

This is highly theoretical question so I can understand epoll better. Please don't refer me to pthreads or libevent, this is not my question. Also, I'm not interested in HTTP implementation of Torrent Tracker protocol.

Similar threads:

  1. Could you recommend some guides about Epoll on Linux
  2. Is there any good examples or tutorial about epoll UDP
  3. Multiple UDP sockets using epoll - Not able to receive data
Community
  • 1
  • 1
artyomboyko
  • 2,781
  • 5
  • 40
  • 54
  • 2
    Why do you need 14 sockets? UDP is connectionless so can't you just do everything with a single socket (and perhaps no epoll)? – John Zwinck Aug 10 '14 at 14:47
  • sounds good :) i think you are right ... can you make an answer ? – artyomboyko Aug 10 '14 at 14:54
  • will i receive data in any particual order ? will i be able to parse it ? – artyomboyko Aug 10 '14 at 16:19
  • 1
    Certainly don't use these raw OS APIs if you can help it. Use a wrapper library like libevent, libev or libuv or Boost Asio. They make all of this fairly easy. – usr Aug 10 '14 at 18:39
  • @JohnZwinck when your server support multiple clients one must use multiple sockets. There is one primary socket used for listening, but then the accept() command creates multiple worker sockets for each incoming client message. UDP is connectionless doesn't mean the socket connection doesn't persist for however long it takes to read and respond to the incoming message. In that time 10 more clients might have sent new data grams. Multiple input sockets typically an array ( used in select() ) means each client's datagram is received and a response can be sent. – JMS Dec 02 '20 at 08:53
  • @usr Libraries like 4 gl languages are excellent way to maximize ones efficiency. However, libraries are never as flexible as writing ones own code. If one requires a higher level of performance or a more nuanced solution, libraries are sometimes not the answer. Coarse if all one is familiar with is libraries calls, one may not even be aware of the performance options available from the lower level calls.. Writing ones own code educates one to the possibilities. – JMS Dec 02 '20 at 08:57

2 Answers2

2

You should just do everything on a single socket. Since UDP is connectionless, you can re-use the same socket for all your sends and receives--you just pass the address explicitly every time you sendto(), and optionally use recvfrom() to know who replied to you.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
-1

to receive data on a particular udp socket you need to bind it.

   int sockfd,n;
   struct sockaddr_in servaddr,cliaddr;
   socklen_t len;
   sockfd=socket(AF_INET,SOCK_DGRAM,0);

   bzero(&servaddr,sizeof(servaddr));
   servaddr.sin_family = AF_INET;
   servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
   servaddr.sin_port=htons(32000);
   bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));

and then call recv or read . you can open different fds like you did, add them to fd set and use select. then you can use FD_ISSET to figure out which fd has data see man page its very useful.

Also, to answer you question in comments.

"will i receive data in any particual order ? will i be able to parse it ?"

IP world has no guarantee on order. its a connection-less world data drops and ECMP which sometimes make sure data is not ordered :).

after the read, recv, recvfrom you will have the data in a buffer which you can easily parse.

Nish
  • 379
  • 2
  • 9