struct mread_pool * mread_create(uint32_t addr, int port , int max , int buffer_size) { int listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd == -1) { return NULL; } if ( -1 == _set_nonblocking(listen_fd) ) { return NULL; } int reuse = 1; setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)); struct sockaddr_in my_addr; memset(&my_addr, 0, sizeof(struct sockaddr_in)); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(port); my_addr.sin_addr.s_addr = addr; // printf("MREAD bind %s:%u\n",inet_ntoa(my_addr.sin_addr),ntohs(my_addr.sin_port)); if (bind(listen_fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { close(listen_fd); return NULL; } if (listen(listen_fd, BACKLOG) == -1) { close(listen_fd); return NULL; } struct mread_pool * self = malloc(sizeof(*self)); self->max_connection = max; self->closed = 0; self->active = -1; self->skip = 0; self->sockets = _create_sockets(max); self->free_socket = &self->sockets[0]; self->queue_len = 0; self->queue_head = 0; if (buffer_size == 0) { self->rb = _create_rb(RINGBUFFER_DEFAULT); } else { self->rb = _create_rb(buffer_size); } #ifdef HAVE_EPOLL int epoll_fd = epoll_create(max + 1); if (epoll_fd == -1) { close(listen_fd); return NULL; } struct epoll_event ev; ev.events = EPOLLIN; ev.data.ptr = LISTENSOCKET; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &ev) == -1) { close(listen_fd); close(epoll_fd); return NULL; } #elif HAVE_KQUEUE int kqueue_fd = kqueue(); if (kqueue_fd == -1) { close(listen_fd); return NULL; } struct kevent ke; EV_SET(&ke, listen_fd, EVFILT_READ, EV_ADD, 0, 0, LISTENSOCKET); if (kevent(kqueue_fd, &ke, 1, NULL, 0, NULL) == -1) { close(listen_fd); close(kqueue_fd); return NULL; } #elif defined(_WIN32) HANDLE iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0,2);//todo fix 2 if(iocp == NULL){ printf("error:create iocp:%d \n",WSAGetLastError()); return NULL; } CreateIoCompletionPort((HANDLE)listen_fd,iocp,listen_fd, 0); GUID guidAcceptEx = WSAID_ACCEPTEX; DWORD dwBytes = 0; if (!WSAIoctl(listen_fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &guidAcceptEx, sizeof(guidAcceptEx), &lpfnAcceptEx, sizeof(lpfnAcceptEx), &dwBytes, NULL, NULL) == 0) { printf("WSAIoctl error:%d \n",WSAGetLastError()); return NULL; } int peer_socket = socket(AF_INET,SOCK_STREAM,0); if(peer_socket== INVALID_SOCKET){ printf("create socket error:%d \n",WSAGetLastError()); return NULL; } struct socket * s2=_add_client(self,peer_socket); BOOL bRet = lpfnAcceptEx(listen_fd,peer_socket,s2->data, 0, sizeof(SOCKADDR_IN)+16, sizeof(SOCKADDR_IN)+16, &dwBytes, &(s2->ol)); if (bRet == FALSE) { if (WSAGetLastError() != ERROR_IO_PENDING){ printf("WSAIoctl error:%d \n",WSAGetLastError()); return NULL; } } #endif self->listen_fd = listen_fd; #ifdef HAVE_EPOLL self->epoll_fd = epoll_fd; #elif HAVE_KQUEUE self->kqueue_fd = kqueue_fd; #elif defined(_WIN32) self->iocp= iocp; #endif return self; }
struct mread_pool * mread_create(uint32_t addr, int port , int max , int buffer_size) { int listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd == -1) { return NULL; } if ( -1 == _set_nonblocking(listen_fd) ) { return NULL; } int reuse = 1; setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)); struct sockaddr_in my_addr; memset(&my_addr, 0, sizeof(struct sockaddr_in)); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(port); my_addr.sin_addr.s_addr = addr; // printf("MREAD bind %s:%u\n",inet_ntoa(my_addr.sin_addr),ntohs(my_addr.sin_port)); if (bind(listen_fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { close(listen_fd); return NULL; } if (listen(listen_fd, BACKLOG) == -1) { close(listen_fd); return NULL; } int epoll_fd = epoll_create(max + 1); if (epoll_fd == -1) { close(listen_fd); return NULL; } struct epoll_event ev; ev.events = EPOLLIN; ev.data.ptr = LISTENSOCKET; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &ev) == -1) { close(listen_fd); close(epoll_fd); return NULL; } struct mread_pool * self = malloc(sizeof(*self)); self->listen_fd = listen_fd; self->epoll_fd = epoll_fd; self->max_connection = max; self->closed = 0; self->active = -1; self->skip = 0; self->sockets = _create_sockets(max); self->free_socket = &self->sockets[0]; self->queue_len = 0; self->queue_head = 0; if (buffer_size == 0) { self->rb = _create_rb(RINGBUFFER_DEFAULT); } else { self->rb = _create_rb(buffer_size); } return self; }