问题描述:

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

网友答案:

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.

网友答案:

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.

相关阅读:
Top