summaryrefslogtreecommitdiff
path: root/bittorrent/epoll_server/epoll_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'bittorrent/epoll_server/epoll_server.c')
-rw-r--r--bittorrent/epoll_server/epoll_server.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/bittorrent/epoll_server/epoll_server.c b/bittorrent/epoll_server/epoll_server.c
new file mode 100644
index 0000000..dc010e6
--- /dev/null
+++ b/bittorrent/epoll_server/epoll_server.c
@@ -0,0 +1,134 @@
+#include "epoll_server.h"
+
+#include <netdb.h>
+#include <stdlib.h>
+#include <sys/epoll.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "connection.h"
+#include "string.h"
+
+int create_and_bind(struct addrinfo *addrinfo)
+{
+ for (struct addrinfo *info = addrinfo; info != NULL; info = info->ai_next)
+ {
+ int sock_fd =
+ socket(info->ai_family, info->ai_socktype, info->ai_protocol);
+ if (sock_fd != -1)
+ {
+ int feur = bind(sock_fd, info->ai_addr, info->ai_addrlen);
+ if (feur != -1)
+ {
+ return sock_fd;
+ }
+ else
+ {
+ close(sock_fd);
+ }
+ }
+ }
+ exit(1);
+}
+
+int prepare_socket(const char *ip, const char *port)
+{
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+ struct addrinfo *addrinfo;
+ int e = getaddrinfo(ip, port, &hints, &addrinfo);
+ if (e != 0)
+ {
+ exit(1);
+ }
+ e = create_and_bind(addrinfo);
+ int e2 = listen(e, 1000);
+ freeaddrinfo(addrinfo);
+ if (e2 == -1)
+ {
+ close(e);
+ exit(1);
+ }
+ return e;
+}
+
+struct connection_t *accept_client(int epoll_instance, int server_socket,
+ struct connection_t *connection)
+{
+ int e = accept(server_socket, NULL, 0);
+ if (e == -1)
+ {
+ close(server_socket);
+ exit(1);
+ }
+ struct epoll_event tmp;
+ tmp.events = EPOLLIN;
+ tmp.data.fd = e;
+ int er = epoll_ctl(epoll_instance, EPOLL_CTL_ADD, e, &tmp);
+ if (er == -1)
+ {
+ close(server_socket);
+ close(e);
+ exit(1);
+ }
+ return add_client(connection, e);
+}
+
+int main(int argc, char **argv)
+{
+ if (argc != 3)
+ {
+ exit(1);
+ }
+ int epoll_instance = epoll_create1(0);
+ if (epoll_instance == -1)
+ {
+ exit(1);
+ }
+ int e = prepare_socket(argv[1], argv[2]);
+ struct connection_t *co = NULL;
+ struct epoll_event tmp;
+ tmp.events = EPOLLIN;
+ tmp.data.fd = e;
+ if (epoll_ctl(epoll_instance, EPOLL_CTL_ADD, e, &tmp) == -1)
+ {
+ close(e);
+ exit(1);
+ }
+ while (1)
+ {
+ struct epoll_event elist[MAX_EVENTS];
+ int info = epoll_wait(epoll_instance, elist, MAX_EVENTS, -1);
+ if (info == -1)
+ {
+ exit(1);
+ }
+ for (int i = 0; i < info; i++)
+ {
+ int fd = elist[i].data.fd;
+ if (fd == e)
+ {
+ co = accept_client(epoll_instance, e, co);
+ }
+ else
+ {
+ char buf[100] = { 0 };
+ int info1 = recv(fd, buf, 100, 0);
+ if (info1 < 1)
+ {
+ co = remove_client(co, fd);
+ close(fd);
+ }
+ else
+ {
+ struct connection_t *tmp = co;
+ while (tmp != NULL)
+ {
+ send(tmp->client_socket, buf, info1, 0);
+ tmp = tmp->next;
+ }
+ }
+ }
+ }
+ }
+}