Schluss fuer heute.

This commit is contained in:
Maximilian Marx 2008-08-19 02:20:10 +02:00
parent 7b914f4d6f
commit 0bf9d52b74
4 changed files with 168 additions and 10 deletions

View File

@ -1,5 +1,15 @@
OBJECTS=xerxes.cxx OBJECTS=xerxes.cxx socket.cxx
BIN=xerxes BIN=xerxes
$(BIN): $(OBJECTS) $(BIN): $(OBJECTS)
g++ -o $(BIN) $(OBJECTS) -Wall -pedantic -ggdb g++ -o $(BIN) $(OBJECTS) -Wall -pedantic -ggdb
all: $(BIN)
test: $(BIN)
./$(BIN)
clean:
rm -f $(BIN) *.o *.cxx~ *.hxx~ Makefile~
.PHONY: all

View File

@ -6,7 +6,6 @@
* Maximilian Marx <mmarx@wh2.tu-dresden.de> * Maximilian Marx <mmarx@wh2.tu-dresden.de>
*/ */
#include <stdexcept>
#include <unistd.h> #include <unistd.h>
#include "socket.hxx" #include "socket.hxx"
@ -23,6 +22,11 @@ namespace xerxes
} }
} }
Socket::Socket(int new_fd)
{
fd = new_fd;
}
Socket::~Socket() Socket::~Socket()
{ {
if(fd) if(fd)
@ -43,12 +47,18 @@ namespace xerxes
return ::listen(socket.fd, backlog); return ::listen(socket.fd, backlog);
} }
int boost::shared_ptr<Socket>
accept(Socket& socket, accept(Socket& socket,
sockaddr* address, sockaddr* address,
socklen_t* address_len) socklen_t* address_len)
{ {
return ::accept(socket.fd, address, address_len); int new_fd = ::accept(socket.fd, address, address_len);
if(new_fd == -1)
{
throw std::runtime_error("could not accept socket.");
}
return boost::shared_ptr<Socket>(new Socket(new_fd));
} }
int int

View File

@ -9,16 +9,21 @@
#ifndef XERXES_SOCKET_HXX #ifndef XERXES_SOCKET_HXX
#define XERXES_SOCKET_HXX #define XERXES_SOCKET_HXX
#include <stdexcept>
#include <utility> #include <utility>
#include <map>
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp> #include <boost/shared_array.hpp>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/epoll.h>
namespace xerxes namespace xerxes
{ {
struct Socket : boost::noncopyable struct Socket : boost::noncopyable
{ {
Socket(int fd);
Socket(int domain, Socket(int domain,
int type, int type,
int protocol); int protocol);
@ -36,7 +41,7 @@ namespace xerxes
MysqlData MysqlData
makeData(int len); makeData(int len);
int boost::shared_ptr<Socket>
accept(Socket& socket, accept(Socket& socket,
sockaddr* address, sockaddr* address,
socklen_t* address_len); socklen_t* address_len);
@ -47,7 +52,7 @@ namespace xerxes
int int
connect(Socket& socket, connect(Socket& socket,
sockaddr const* const serv_address, sockaddr const* const serv_address,
socklen_t* address_len); socklen_t address_len);
int int
recv(Socket& socket, recv(Socket& socket,
@ -64,6 +69,63 @@ namespace xerxes
sockaddr const* const bind_address, sockaddr const* const bind_address,
socklen_t addrlen); socklen_t addrlen);
struct EPoll
{
EPoll() : fd(epoll_create(64))
{
if(fd < 0)
{
throw std::runtime_error("could not create epoll descriptor.");
}
}
virtual ~EPoll()
{
if(fd > 0)
{
close(fd);
}
}
typedef boost::shared_ptr<epoll_event> event_t;
void
add(Socket const& source,
Socket const& target)
{
events[source.fd] = event_t(new epoll_event);
events[target.fd] = event_t(new epoll_event);
events[source.fd]->events = EPOLLIN;
| EPOLLPRI | EPOLLERR | EPOLLHUP;
events[target.fd]->events = events[source.fd]->events;
events[source.fd]->data.fd = target.fd;
events[target.fd]->data.fd = source.fd;
epoll_ctl(fd, EPOLL_CTL_ADD, source.fd, events[source.fd].get());
epoll_ctl(fd, EPOLL_CTL_ADD, target.fd, events[target.fd].get());
}
void
add(Socket const& socket)
{
events[socket.fd] = event_t(new epoll_event);
events[socket.fd]->events = EPOLLIN;
events[socket.fd]->data.fd = -1;
epoll_ctl(fd, EPOLL_CTL_ADD, socket.fd, events[socket.fd].get());
}
void
del(Socket const& socket)
{
epoll_ctl(fd, EPOLL_CTL_DEL, socket.fd, 0);
events.erase(socket.fd);
}
int fd;
std::map<int, event_t> events;
};
} }
#endif #endif

View File

@ -6,12 +6,88 @@
* Maximilian Marx <mmarx@wh2.tu-dresden.de> * Maximilian Marx <mmarx@wh2.tu-dresden.de>
*/ */
#include <iostream> #include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "socket.hxx"
int int
main(int argc, char* argv[]) main(int argc, char* argv[])
{ {
std::cout << "Hello, World!"; using namespace std;
using namespace xerxes;
cout << "Hello, World!" << endl
<< "ich kanns auch lassen, hier `Hello, World!' zu schreiben..."
<< endl;
Socket lstn(PF_INET, SOCK_STREAM, 0);
addrinfo hints;
addrinfo* res;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
getaddrinfo("127.0.0.1", "13337", &hints, &res);
bind(lstn, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
int ret = listen(lstn, 3);
EPoll epoll;
epoll.add(lstn);
const int max_events = 23;
boost::shared_array<epoll_event> events(new epoll_event[max_events]);
std::map<int, boost::shared_ptr<Socket> > sockets;
for(;;)
{
int num = epoll_wait(epoll.fd, events.get(), max_events, -1);
for(int i = 0; i < num; ++i)
{
if((events[i].data.fd == -1)
&& (events[i].events & EPOLLIN))
{
//close(accept(lstn, 0, 0));
//cout << "hollo!" << endl;
boost::shared_ptr<Socket> target(new Socket(PF_INET, SOCK_STREAM, 0));
addrinfo hints;
addrinfo* res;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
getaddrinfo("127.0.0.1", "3306", &hints, &res);
connect(*target, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
sockets[target->fd] = target;
boost::shared_ptr<Socket> source(accept(lstn, 0, 0));
sockets[source->fd] = source;
epoll.add(*source, *target);
}
else{ cout << "hollo!" << events[i].data.fd << endl; }
}
}
return 0; return 0;
} }