Hi,
I'm trying to use raw sockets with libev, but have a problem getting
READ events firing. I have attached a example source code which
demonstrates my problem. I'm using 32bit Ubuntu 10.04 and the packaged
version of libev (3.8). Similar code with normal UDP sockets worked
fine.
/Torste Aikio
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <net/ethernet.h> /* the L2 protocols */
#include <netinet/in.h>
#include <netpacket/packet.h>
#include <ev++.h>
#include <string>
#ifndef MAX_MESG_SIZE
#define MAX_MESG_SIZE 1500
#endif
class Socket {
public:
Socket(const std::string &interface, int port);
~Socket();
void onSocketReadable(ev::io &w, int revents);
private:
std::string ifaceName;
int listenSocket;
int listenPort;
ev::io watcher;
void initSocket(const std::string &interface, int port);
};
Socket::Socket(const std::string &interface, int port)
: ifaceName(interface), listenPort(port)
{
initSocket(interface, port);
watcher.set<Socket, &Socket::onSocketReadable> (this);
watcher.start(listenSocket, ev::READ);
}
Socket::~Socket()
{
watcher.stop();
close(listenSocket);
}
void Socket::initSocket(const std::string &interface, int port)
{
listenSocket = socket(PF_PACKET, SOCK_RAW, IPPROTO_IP);
if (listenSocket < 0)
{
throw std::runtime_error(std::string("socket: ") + strerror(errno));
}
if (fcntl(listenSocket, F_SETFL, O_NONBLOCK) < 0)
{
throw std::runtime_error(std::string("fcntl(O_NONBLOCK): ") + strerror(errno));
}
}
void Socket::onSocketReadable(ev::io &w, int revents)
{
fprintf(stderr, "Got incoming data\n");
u_int8_t * mesg = (u_int8_t*)malloc(MAX_MESG_SIZE);
struct sockaddr_ll clientAddr = {0};
socklen_t clientAddrLength = sizeof(clientAddr);
int size = recvfrom(listenSocket, mesg, MAX_MESG_SIZE, 0,
(struct sockaddr *) &clientAddr, &clientAddrLength);
if (size < 0)
{
perror("recvfrom");
}
free(mesg);
}
int main (int,char**)
{
struct ev_loop *loop = EV_DEFAULT;
Socket socket("eth1", 6767);
ev_loop(loop, 0);
return 0;
}
_______________________________________________
libev mailing list
[email protected]
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev