resp协议定义, xml定义配置文件
This commit is contained in:
672
NtyCo/core/nty_socket.c
Executable file
672
NtyCo/core/nty_socket.c
Executable file
@@ -0,0 +1,672 @@
|
||||
/*
|
||||
* Author : WangBoJing , email : 1989wangbojing@gmail.com
|
||||
*
|
||||
* Copyright Statement:
|
||||
* --------------------
|
||||
* This software is protected by Copyright and the information contained
|
||||
* herein is confidential. The software may not be copied and the information
|
||||
* contained herein may not be used or disclosed except with the written
|
||||
* permission of Author. (C) 2017
|
||||
*
|
||||
*
|
||||
|
||||
**** ***** *****
|
||||
*** * ** ***
|
||||
*** * * * **
|
||||
* ** * * ** **
|
||||
* ** * * ** *
|
||||
* ** * ** ** *
|
||||
* ** * *** **
|
||||
* ** * *********** ***** ***** ** ****
|
||||
* ** * ** ** ** ** ** **
|
||||
* ** * ** ** * ** * **
|
||||
* ** * ** * * ** ** **
|
||||
* ** * ** ** * ** * **
|
||||
* ** * ** * * ** ** **
|
||||
* ** * ** ** * ** ** **
|
||||
* ** * ** ** * ** ** **
|
||||
* ** * ** * * ** ** **
|
||||
* ** * ** ** * ** * ** **
|
||||
* *** ** * * ** * ** **
|
||||
* *** ** * ** * * ** **
|
||||
* ** ** * ** ** * ** **
|
||||
* ** ** * * ** * ** **
|
||||
***** * **** * ***** ****
|
||||
*
|
||||
*
|
||||
*****
|
||||
****
|
||||
|
||||
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nty_coroutine.h"
|
||||
|
||||
|
||||
|
||||
static uint32_t nty_pollevent_2epoll( short events )
|
||||
{
|
||||
uint32_t e = 0;
|
||||
if( events & POLLIN ) e |= EPOLLIN;
|
||||
if( events & POLLOUT ) e |= EPOLLOUT;
|
||||
if( events & POLLHUP ) e |= EPOLLHUP;
|
||||
if( events & POLLERR ) e |= EPOLLERR;
|
||||
if( events & POLLRDNORM ) e |= EPOLLRDNORM;
|
||||
if( events & POLLWRNORM ) e |= EPOLLWRNORM;
|
||||
return e;
|
||||
}
|
||||
static short nty_epollevent_2poll( uint32_t events )
|
||||
{
|
||||
short e = 0;
|
||||
if( events & EPOLLIN ) e |= POLLIN;
|
||||
if( events & EPOLLOUT ) e |= POLLOUT;
|
||||
if( events & EPOLLHUP ) e |= POLLHUP;
|
||||
if( events & EPOLLERR ) e |= POLLERR;
|
||||
if( events & EPOLLRDNORM ) e |= POLLRDNORM;
|
||||
if( events & EPOLLWRNORM ) e |= POLLWRNORM;
|
||||
return e;
|
||||
}
|
||||
/*
|
||||
* nty_poll_inner --> 1. sockfd--> epoll, 2 yield, 3. epoll x sockfd
|
||||
* fds :
|
||||
*/
|
||||
|
||||
static int nty_poll_inner(struct pollfd *fds, nfds_t nfds, int timeout) {
|
||||
|
||||
if (timeout == 0)
|
||||
{
|
||||
return poll(fds, nfds, timeout);
|
||||
}
|
||||
if (timeout < 0)
|
||||
{
|
||||
timeout = INT_MAX;
|
||||
}
|
||||
|
||||
nty_schedule *sched = nty_coroutine_get_sched();
|
||||
if (sched == NULL) {
|
||||
printf("scheduler not exit!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
nty_coroutine *co = sched->curr_thread;
|
||||
|
||||
int i = 0;
|
||||
for (i = 0;i < nfds;i ++) {
|
||||
|
||||
struct epoll_event ev;
|
||||
ev.events = nty_pollevent_2epoll(fds[i].events);
|
||||
ev.data.fd = fds[i].fd;
|
||||
epoll_ctl(sched->poller_fd, EPOLL_CTL_ADD, fds[i].fd, &ev);
|
||||
|
||||
co->events = fds[i].events;
|
||||
nty_schedule_sched_wait(co, fds[i].fd, fds[i].events, timeout);
|
||||
}
|
||||
nty_coroutine_yield(co);
|
||||
|
||||
for (i = 0;i < nfds;i ++) {
|
||||
|
||||
struct epoll_event ev;
|
||||
ev.events = nty_pollevent_2epoll(fds[i].events);
|
||||
ev.data.fd = fds[i].fd;
|
||||
epoll_ctl(sched->poller_fd, EPOLL_CTL_DEL, fds[i].fd, &ev);
|
||||
|
||||
nty_schedule_desched_wait(fds[i].fd);
|
||||
}
|
||||
|
||||
return nfds;
|
||||
}
|
||||
|
||||
|
||||
int nty_socket(int domain, int type, int protocol) {
|
||||
|
||||
int fd = socket(domain, type, protocol);
|
||||
if (fd == -1) {
|
||||
printf("Failed to create a new socket\n");
|
||||
return -1;
|
||||
}
|
||||
int ret = fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
if (ret == -1) {
|
||||
close(ret);
|
||||
return -1;
|
||||
}
|
||||
int reuse = 1;
|
||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
//nty_accept
|
||||
//return failed == -1, success > 0
|
||||
|
||||
int nty_accept(int fd, struct sockaddr *addr, socklen_t *len) {
|
||||
int sockfd = -1;
|
||||
int timeout = 1;
|
||||
nty_coroutine *co = nty_coroutine_get_sched()->curr_thread;
|
||||
|
||||
while (1) {
|
||||
struct pollfd fds;
|
||||
fds.fd = fd;
|
||||
fds.events = POLLIN | POLLERR | POLLHUP;
|
||||
nty_poll_inner(&fds, 1, timeout);
|
||||
|
||||
sockfd = accept(fd, addr, len);
|
||||
if (sockfd < 0) {
|
||||
if (errno == EAGAIN) {
|
||||
continue;
|
||||
} else if (errno == ECONNABORTED) {
|
||||
printf("accept : ECONNABORTED\n");
|
||||
|
||||
} else if (errno == EMFILE || errno == ENFILE) {
|
||||
printf("accept : EMFILE || ENFILE\n");
|
||||
}
|
||||
return -1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int ret = fcntl(sockfd, F_SETFL, O_NONBLOCK);
|
||||
if (ret == -1) {
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
int reuse = 1;
|
||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
|
||||
int nty_connect(int fd, struct sockaddr *name, socklen_t namelen) {
|
||||
|
||||
int ret = 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
struct pollfd fds;
|
||||
fds.fd = fd;
|
||||
fds.events = POLLOUT | POLLERR | POLLHUP;
|
||||
nty_poll_inner(&fds, 1, 1);
|
||||
|
||||
ret = connect(fd, name, namelen);
|
||||
if (ret == 0) break;
|
||||
|
||||
if (ret == -1 && (errno == EAGAIN ||
|
||||
errno == EWOULDBLOCK ||
|
||||
errno == EINPROGRESS)) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//recv
|
||||
// add epoll first
|
||||
//
|
||||
ssize_t nty_recv(int fd, void *buf, size_t len, int flags) {
|
||||
|
||||
struct pollfd fds;
|
||||
fds.fd = fd;
|
||||
fds.events = POLLIN | POLLERR | POLLHUP;
|
||||
|
||||
nty_poll_inner(&fds, 1, 1);
|
||||
|
||||
int ret = recv(fd, buf, len, flags);
|
||||
if (ret < 0) {
|
||||
//if (errno == EAGAIN) return ret;
|
||||
if (errno == ECONNRESET) return -1;
|
||||
//printf("recv error : %d, ret : %d\n", errno, ret);
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ssize_t nty_send(int fd, const void *buf, size_t len, int flags) {
|
||||
|
||||
int sent = 0;
|
||||
|
||||
int ret = send(fd, ((char*)buf)+sent, len-sent, flags);
|
||||
if (ret == 0) return ret;
|
||||
if (ret > 0) sent += ret;
|
||||
|
||||
while (sent < len) {
|
||||
struct pollfd fds;
|
||||
fds.fd = fd;
|
||||
fds.events = POLLOUT | POLLERR | POLLHUP;
|
||||
|
||||
nty_poll_inner(&fds, 1, 1);
|
||||
ret = send(fd, ((char*)buf)+sent, len-sent, flags);
|
||||
//printf("send --> len : %d\n", ret);
|
||||
if (ret <= 0) {
|
||||
break;
|
||||
}
|
||||
sent += ret;
|
||||
}
|
||||
|
||||
if (ret <= 0 && sent == 0) return ret;
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
|
||||
ssize_t nty_sendto(int fd, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *dest_addr, socklen_t addrlen) {
|
||||
|
||||
|
||||
int sent = 0;
|
||||
|
||||
while (sent < len) {
|
||||
struct pollfd fds;
|
||||
fds.fd = fd;
|
||||
fds.events = POLLOUT | POLLERR | POLLHUP;
|
||||
|
||||
nty_poll_inner(&fds, 1, 1);
|
||||
int ret = sendto(fd, ((char*)buf)+sent, len-sent, flags, dest_addr, addrlen);
|
||||
if (ret <= 0) {
|
||||
if (errno == EAGAIN) continue;
|
||||
else if (errno == ECONNRESET) {
|
||||
return ret;
|
||||
}
|
||||
printf("send errno : %d, ret : %d\n", errno, ret);
|
||||
assert(0);
|
||||
}
|
||||
sent += ret;
|
||||
}
|
||||
return sent;
|
||||
|
||||
}
|
||||
|
||||
ssize_t nty_recvfrom(int fd, void *buf, size_t len, int flags,
|
||||
struct sockaddr *src_addr, socklen_t *addrlen) {
|
||||
|
||||
struct pollfd fds;
|
||||
fds.fd = fd;
|
||||
fds.events = POLLIN | POLLERR | POLLHUP;
|
||||
|
||||
nty_poll_inner(&fds, 1, 1);
|
||||
|
||||
int ret = recvfrom(fd, buf, len, flags, src_addr, addrlen);
|
||||
if (ret < 0) {
|
||||
if (errno == EAGAIN) return ret;
|
||||
if (errno == ECONNRESET) return 0;
|
||||
|
||||
printf("recv error : %d, ret : %d\n", errno, ret);
|
||||
assert(0);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int nty_close(int fd) {
|
||||
#if 0
|
||||
nty_schedule *sched = nty_coroutine_get_sched();
|
||||
|
||||
nty_coroutine *co = sched->curr_thread;
|
||||
if (co) {
|
||||
TAILQ_INSERT_TAIL(&nty_coroutine_get_sched()->ready, co, ready_next);
|
||||
co->status |= BIT(NTY_COROUTINE_STATUS_FDEOF);
|
||||
}
|
||||
#endif
|
||||
return close(fd);
|
||||
}
|
||||
|
||||
|
||||
#ifdef COROUTINE_HOOK
|
||||
|
||||
socket_t socket_f = NULL;
|
||||
|
||||
read_t read_f = NULL;
|
||||
recv_t recv_f = NULL;
|
||||
recvfrom_t recvfrom_f = NULL;
|
||||
|
||||
write_t write_f = NULL;
|
||||
send_t send_f = NULL;
|
||||
sendto_t sendto_f = NULL;
|
||||
|
||||
accept_t accept_f = NULL;
|
||||
close_t close_f = NULL;
|
||||
connect_t connect_f = NULL;
|
||||
|
||||
|
||||
int init_hook(void) {
|
||||
|
||||
socket_f = (socket_t)dlsym(RTLD_NEXT, "socket");
|
||||
|
||||
read_f = (read_t)dlsym(RTLD_NEXT, "read");
|
||||
recv_f = (recv_t)dlsym(RTLD_NEXT, "recv");
|
||||
recvfrom_f = (recvfrom_t)dlsym(RTLD_NEXT, "recvfrom");
|
||||
|
||||
write_f = (write_t)dlsym(RTLD_NEXT, "write");
|
||||
send_f = (send_t)dlsym(RTLD_NEXT, "send");
|
||||
sendto_f = (sendto_t)dlsym(RTLD_NEXT, "sendto");
|
||||
|
||||
accept_f = (accept_t)dlsym(RTLD_NEXT, "accept");
|
||||
close_f = (close_t)dlsym(RTLD_NEXT, "close");
|
||||
connect_f = (connect_t)dlsym(RTLD_NEXT, "connect");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int socket(int domain, int type, int protocol) {
|
||||
|
||||
if (!socket_f) init_hook();
|
||||
|
||||
nty_schedule *sched = nty_coroutine_get_sched();
|
||||
if (sched == NULL) {
|
||||
return socket_f(domain, type, protocol);
|
||||
}
|
||||
|
||||
int fd = socket_f(domain, type, protocol);
|
||||
if (fd == -1) {
|
||||
printf("Failed to create a new socket\n");
|
||||
return -1;
|
||||
}
|
||||
int ret = fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
if (ret == -1) {
|
||||
close(ret);
|
||||
return -1;
|
||||
}
|
||||
int reuse = 1;
|
||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
ssize_t read(int fd, void *buf, size_t count) {
|
||||
|
||||
if (!read_f) init_hook();
|
||||
|
||||
nty_schedule *sched = nty_coroutine_get_sched();
|
||||
if (sched == NULL) {
|
||||
return read_f(fd, buf, count);
|
||||
}
|
||||
|
||||
struct pollfd fds;
|
||||
fds.fd = fd;
|
||||
fds.events = POLLIN | POLLERR | POLLHUP;
|
||||
|
||||
nty_poll_inner(&fds, 1, 1);
|
||||
|
||||
int ret = read_f(fd, buf, count);
|
||||
if (ret < 0) {
|
||||
//if (errno == EAGAIN) return ret;
|
||||
if (errno == ECONNRESET) return -1;
|
||||
//printf("recv error : %d, ret : %d\n", errno, ret);
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t recv(int fd, void *buf, size_t len, int flags) {
|
||||
|
||||
if (!recv_f) init_hook();
|
||||
|
||||
nty_schedule *sched = nty_coroutine_get_sched();
|
||||
if (sched == NULL) {
|
||||
return recv_f(fd, buf, len, flags);
|
||||
}
|
||||
|
||||
struct pollfd fds;
|
||||
fds.fd = fd;
|
||||
fds.events = POLLIN | POLLERR | POLLHUP;
|
||||
|
||||
nty_poll_inner(&fds, 1, 1);
|
||||
|
||||
int ret = recv_f(fd, buf, len, flags);
|
||||
if (ret < 0) {
|
||||
//if (errno == EAGAIN) return ret;
|
||||
if (errno == ECONNRESET) return -1;
|
||||
//printf("recv error : %d, ret : %d\n", errno, ret);
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ssize_t recvfrom(int fd, void *buf, size_t len, int flags,
|
||||
struct sockaddr *src_addr, socklen_t *addrlen) {
|
||||
|
||||
if (!recvfrom_f) init_hook();
|
||||
|
||||
nty_schedule *sched = nty_coroutine_get_sched();
|
||||
if (sched == NULL) {
|
||||
return recvfrom_f(fd, buf, len, flags, src_addr, addrlen);
|
||||
}
|
||||
|
||||
struct pollfd fds;
|
||||
fds.fd = fd;
|
||||
fds.events = POLLIN | POLLERR | POLLHUP;
|
||||
|
||||
nty_poll_inner(&fds, 1, 1);
|
||||
|
||||
int ret = recvfrom_f(fd, buf, len, flags, src_addr, addrlen);
|
||||
if (ret < 0) {
|
||||
if (errno == EAGAIN) return ret;
|
||||
if (errno == ECONNRESET) return 0;
|
||||
|
||||
printf("recv error : %d, ret : %d\n", errno, ret);
|
||||
assert(0);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
ssize_t write(int fd, const void *buf, size_t count) {
|
||||
|
||||
if (!write_f) init_hook();
|
||||
|
||||
nty_schedule *sched = nty_coroutine_get_sched();
|
||||
if (sched == NULL) {
|
||||
return write_f(fd, buf, count);
|
||||
}
|
||||
|
||||
int sent = 0;
|
||||
|
||||
int ret = write_f(fd, ((char*)buf)+sent, count-sent);
|
||||
if (ret == 0) return ret;
|
||||
if (ret > 0) sent += ret;
|
||||
|
||||
while (sent < count) {
|
||||
struct pollfd fds;
|
||||
fds.fd = fd;
|
||||
fds.events = POLLOUT | POLLERR | POLLHUP;
|
||||
|
||||
nty_poll_inner(&fds, 1, 1);
|
||||
ret = write_f(fd, ((char*)buf)+sent, count-sent);
|
||||
//printf("send --> len : %d\n", ret);
|
||||
if (ret <= 0) {
|
||||
break;
|
||||
}
|
||||
sent += ret;
|
||||
}
|
||||
|
||||
if (ret <= 0 && sent == 0) return ret;
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
|
||||
ssize_t send(int fd, const void *buf, size_t len, int flags) {
|
||||
|
||||
if (!send_f) init_hook();
|
||||
|
||||
nty_schedule *sched = nty_coroutine_get_sched();
|
||||
if (sched == NULL) {
|
||||
return send_f(fd, buf, len, flags);
|
||||
}
|
||||
|
||||
int sent = 0;
|
||||
|
||||
int ret = send_f(fd, ((char*)buf)+sent, len-sent, flags);
|
||||
if (ret == 0) return ret;
|
||||
if (ret > 0) sent += ret;
|
||||
|
||||
while (sent < len) {
|
||||
struct pollfd fds;
|
||||
fds.fd = fd;
|
||||
fds.events = POLLOUT | POLLERR | POLLHUP;
|
||||
|
||||
nty_poll_inner(&fds, 1, 1);
|
||||
ret = send_f(fd, ((char*)buf)+sent, len-sent, flags);
|
||||
//printf("send --> len : %d\n", ret);
|
||||
if (ret <= 0) {
|
||||
break;
|
||||
}
|
||||
sent += ret;
|
||||
}
|
||||
|
||||
if (ret <= 0 && sent == 0) return ret;
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *dest_addr, socklen_t addrlen) {
|
||||
|
||||
if (!sendto_f) init_hook();
|
||||
|
||||
nty_schedule *sched = nty_coroutine_get_sched();
|
||||
if (sched == NULL) {
|
||||
return sendto_f(sockfd, buf, len, flags, dest_addr, addrlen);
|
||||
}
|
||||
|
||||
struct pollfd fds;
|
||||
fds.fd = sockfd;
|
||||
fds.events = POLLOUT | POLLERR | POLLHUP;
|
||||
|
||||
nty_poll_inner(&fds, 1, 1);
|
||||
|
||||
int ret = sendto_f(sockfd, buf, len, flags, dest_addr, addrlen);
|
||||
if (ret < 0) {
|
||||
if (errno == EAGAIN) return ret;
|
||||
if (errno == ECONNRESET) return 0;
|
||||
|
||||
printf("recv error : %d, ret : %d\n", errno, ret);
|
||||
assert(0);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int accept(int fd, struct sockaddr *addr, socklen_t *len) {
|
||||
|
||||
if (!accept_f) init_hook();
|
||||
|
||||
nty_schedule *sched = nty_coroutine_get_sched();
|
||||
if (sched == NULL) {
|
||||
return accept_f(fd, addr, len);
|
||||
}
|
||||
|
||||
int sockfd = -1;
|
||||
int timeout = 1;
|
||||
nty_coroutine *co = nty_coroutine_get_sched()->curr_thread;
|
||||
|
||||
while (1) {
|
||||
struct pollfd fds;
|
||||
fds.fd = fd;
|
||||
fds.events = POLLIN | POLLERR | POLLHUP;
|
||||
nty_poll_inner(&fds, 1, timeout);
|
||||
|
||||
sockfd = accept_f(fd, addr, len);
|
||||
if (sockfd < 0) {
|
||||
if (errno == EAGAIN) {
|
||||
continue;
|
||||
} else if (errno == ECONNABORTED) {
|
||||
printf("accept : ECONNABORTED\n");
|
||||
|
||||
} else if (errno == EMFILE || errno == ENFILE) {
|
||||
printf("accept : EMFILE || ENFILE\n");
|
||||
}
|
||||
return -1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int ret = fcntl(sockfd, F_SETFL, O_NONBLOCK);
|
||||
if (ret == -1) {
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
int reuse = 1;
|
||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
int close(int fd) {
|
||||
|
||||
if (!close_f) init_hook();
|
||||
|
||||
return close_f(fd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int connect(int fd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
|
||||
if (!connect_f) init_hook();
|
||||
|
||||
nty_schedule *sched = nty_coroutine_get_sched();
|
||||
if (sched == NULL) {
|
||||
return connect_f(fd, addr, addrlen);
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
struct pollfd fds;
|
||||
fds.fd = fd;
|
||||
fds.events = POLLOUT | POLLERR | POLLHUP;
|
||||
nty_poll_inner(&fds, 1, 1);
|
||||
|
||||
ret = connect_f(fd, addr, addrlen);
|
||||
if (ret == 0) break;
|
||||
|
||||
if (ret == -1 && (errno == EAGAIN ||
|
||||
errno == EWOULDBLOCK ||
|
||||
errno == EINPROGRESS)) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user