Skip to content

Instantly share code, notes, and snippets.

@loggerhead
Created August 13, 2018 14:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loggerhead/ffc9c131726174143b375fe64f408286 to your computer and use it in GitHub Desktop.
Save loggerhead/ffc9c131726174143b375fe64f408286 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#include "co_routine.h"
using namespace std;
int co_accept(int fd, struct sockaddr *addr, socklen_t *len);
int set_non_block(int fd)
{
int flags = fcntl(fd, F_GETFL, 0) | O_NONBLOCK | O_NDELAY;
return fcntl(fd, F_SETFL, flags);
}
void *handle_read(void *p_handle_fd)
{
int fd = *(int *) p_handle_fd;
printf("handle_read[%d]\n", fd);
struct pollfd pf = {
.fd = fd,
.events = (POLLIN | POLLERR | POLLHUP),
};
co_enable_hook_sys();
while (true) {
char buf[4096];
co_poll(co_get_epoll_ct(), &pf, 1, -1);
int nread = read(pf.fd, buf, sizeof(buf));
if (nread > 0) {
printf("[%d]: %s\n", fd, buf);
for (int nwrite = 0; nwrite < nread; ) {
nwrite += write(pf.fd, buf, nread);
}
} else if (nread == 0) {
printf("close(%d) because %d\n", fd, nread);
close(fd);
break;
}
}
return NULL;
}
void *handle_accept(void *p_listen_fd)
{
printf("handle_accept\n");
int listen_fd = *(int *) p_listen_fd;
struct pollfd pf = {
.fd = listen_fd,
.events = (POLLIN | POLLERR | POLLHUP),
};
co_enable_hook_sys();
while (true)
{
struct sockaddr_in addr = {0};
socklen_t len = sizeof(addr);
int fd = co_accept(listen_fd, (struct sockaddr *)&addr, &len);
if (fd < 0) {
printf("listen...\n");
co_poll(co_get_epoll_ct(), &pf, 1, -1);
} else {
printf("accept [%d]\n", fd);
set_non_block(fd);
stCoRoutine_t *handle_co = NULL;
co_create(&handle_co, NULL, handle_read, &fd);
co_resume(handle_co);
}
}
return 0;
}
int main(int argc, char *argv[])
{
const char *ip = "127.0.0.1";
const int port = 9988;
// create socket
int listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
int reuse = 1;
setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int));
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(INADDR_ANY),
.sin_port = htons(port),
};
// listen socket
if (bind(listen_fd, (struct sockaddr *) &addr, sizeof(addr)) != 0)
{
printf("bind[%d] on %s:%d failed!\n", listen_fd, ip, port);
close(listen_fd);
return -1;
}
listen(listen_fd, 1024);
set_non_block(listen_fd);
printf("listen[%d] on %s:%d\n", listen_fd, ip, port);
// create listen coroutine
stCoRoutine_t *accept_co = NULL;
co_create(&accept_co, NULL, handle_accept, &listen_fd);
co_resume(accept_co);
co_eventloop(co_get_epoll_ct(), 0, 0);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment