unix网络——epoll简单服务器
2014-12-28 00:00
204 查看
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdlib.h>
#define SERV_PORT 5358
#define MAX_CONN 1024
#define EVENT_NUM 1024
#define EPOLL_SIZE 1024
#define BUF_LEN 1024
int setnonblocking(int fd){
int opts;
if((opts = fcntl(fd, F_GETFL))<0){
return -1;
}
opts |=O_NONBLOCK;
if(fcntl(fd, F_SETFL, opts)<0){
return -1;
}
return 0;
}
void *str_echo(void *arg){
int sockfd;
ssize_t nread;
char buf[BUF_LEN] = {0};
pthread_detach(pthread_self());
sockfd = *(int *)arg;
while(1) {
bzero(buf, BUF_LEN);
if((nread = read(sockfd, buf, BUF_LEN)) == -1) {
if(errno == EINTR) {
continue;
}
else {
printf("read error: %s\n", strerror(errno));
continue;
}
}
else if (nread == 0) {
break;
}
else {
//fputs(buf, stdout);
write(sockfd, buf, nread);
}
}
return NULL;
}
int main(int argc, char **argv)
{
int listenfd, connfd, epfd, nfds;
socklen_t addrlen;
struct sockaddr_in cliaddr, servaddr;
struct epoll_event ev, events[EVENT_NUM];
pthread_t tid;
//create socket fd
if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
printf("Create socket error!\n");
return 0;
}
if (setnonblocking(listenfd) == -1){
printf("setnonblicking error!\n");
close(listenfd);
return 0;
}
//bind
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1){
printf("Socket bind error!\n");
close(listenfd);
return 0;
}
//listen
if(listen(listenfd, MAX_CONN) == -1){
printf("listen error\n");
close(listenfd);
return 0;
}
//create epoll
if((epfd = epoll_create(EPOLL_SIZE)) == -1){
printf("Create epoll error!\n");
close(listenfd);
return 0;
}
//register epoll event
ev.data.fd = listenfd;
ev.events = EPOLLIN | EPOLLET;
if ((epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev)) == -1){
printf("epoll_ctl error!\n");
close(listenfd);
return 0;
}
while(1){
if((nfds = epoll_wait(epfd, events, EVENT_NUM, -1)) ==-1){
if(errno == EINTR){
printf("%s\n", strerror(errno));
continue;
}
else{
printf("epoll_wait error!\n");
continue;
}
}
int i;
for(i=0;i<nfds;i++){
if(events[i].data.fd == listenfd){
addrlen = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &addrlen);
if(connfd == -1){
printf("%s\n", strerror(errno));
continue;
}
printf("New Connection %d\n", connfd);
ev.data.fd = connfd;
ev.events = EPOLLIN | EPOLLET;
if((epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev)) == -1){
printf("connect failed!\n");
}
}
else{
if((pthread_create(&tid, NULL, str_echo, &events.data.fd)) == -1) {
exit(0);
}
}
}
}
return 0;
}
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdlib.h>
#define SERV_PORT 5358
#define MAX_CONN 1024
#define EVENT_NUM 1024
#define EPOLL_SIZE 1024
#define BUF_LEN 1024
int setnonblocking(int fd){
int opts;
if((opts = fcntl(fd, F_GETFL))<0){
return -1;
}
opts |=O_NONBLOCK;
if(fcntl(fd, F_SETFL, opts)<0){
return -1;
}
return 0;
}
void *str_echo(void *arg){
int sockfd;
ssize_t nread;
char buf[BUF_LEN] = {0};
pthread_detach(pthread_self());
sockfd = *(int *)arg;
while(1) {
bzero(buf, BUF_LEN);
if((nread = read(sockfd, buf, BUF_LEN)) == -1) {
if(errno == EINTR) {
continue;
}
else {
printf("read error: %s\n", strerror(errno));
continue;
}
}
else if (nread == 0) {
break;
}
else {
//fputs(buf, stdout);
write(sockfd, buf, nread);
}
}
return NULL;
}
int main(int argc, char **argv)
{
int listenfd, connfd, epfd, nfds;
socklen_t addrlen;
struct sockaddr_in cliaddr, servaddr;
struct epoll_event ev, events[EVENT_NUM];
pthread_t tid;
//create socket fd
if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
printf("Create socket error!\n");
return 0;
}
if (setnonblocking(listenfd) == -1){
printf("setnonblicking error!\n");
close(listenfd);
return 0;
}
//bind
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1){
printf("Socket bind error!\n");
close(listenfd);
return 0;
}
//listen
if(listen(listenfd, MAX_CONN) == -1){
printf("listen error\n");
close(listenfd);
return 0;
}
//create epoll
if((epfd = epoll_create(EPOLL_SIZE)) == -1){
printf("Create epoll error!\n");
close(listenfd);
return 0;
}
//register epoll event
ev.data.fd = listenfd;
ev.events = EPOLLIN | EPOLLET;
if ((epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev)) == -1){
printf("epoll_ctl error!\n");
close(listenfd);
return 0;
}
while(1){
if((nfds = epoll_wait(epfd, events, EVENT_NUM, -1)) ==-1){
if(errno == EINTR){
printf("%s\n", strerror(errno));
continue;
}
else{
printf("epoll_wait error!\n");
continue;
}
}
int i;
for(i=0;i<nfds;i++){
if(events[i].data.fd == listenfd){
addrlen = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &addrlen);
if(connfd == -1){
printf("%s\n", strerror(errno));
continue;
}
printf("New Connection %d\n", connfd);
ev.data.fd = connfd;
ev.events = EPOLLIN | EPOLLET;
if((epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev)) == -1){
printf("connect failed!\n");
}
}
else{
if((pthread_create(&tid, NULL, str_echo, &events.data.fd)) == -1) {
exit(0);
}
}
}
}
return 0;
}
相关文章推荐
- Linux网络编程-简单的客户端和服务器通讯程序开发入门(2)
- Linux网络管理之四:创建一个简单的vsftpd服务器
- ElasticBox: 丢掉服务器吧 开发网络应用是如此的简单
- 在Linux上开发网络服务器的一些相关细节:poll与epoll
- NFS(网络文件系统)服务器简单解析
- 用ASP简单封装了几个函数,使用ServerXMLHTTP把网络上的文件保存到本地服务器.
- 用libev的c语言版本实现简单的网络通信服务器
- Linux 网络编程基础---------------客户端/服务器的简单实现
- 在Linux上开发网络服务器的一些相关细节:poll与epoll
- 简单的linuxepoll服务器开发
- 网络编程--简单实现javaftp服务器
- UNIX环境高级编程学习之第十六章网络IPC:套接字 - 非阻塞的Socket通信EPoll模型(多路复用), 实用Socket通信模板
- UNIX环境高级编程学习之第十六章网络IPC:套接字 - 简单UDP Socket 通信
- 读书笔记-最简单的web服务器:网络插座Socket
- 网络通信基础——MFC简单服务器客户端TCP通信
- Windows网络编程示例一——简单的echo服务器
- UNIX环境高级编程学习之第十六章网络IPC:套接字 - 简单TCP Socket 通信
- 有专用DHCP服务器的网络的简单配置
- acl_cpp 简单实用、功能强大的C++网络应用与服务器框架库发布
- UNIX TCP回射服务器/客户端(4):使用epoll模型的服务器