Linux 网络编程 epoll 文件描述符
服务器端新建一个监听套接字时,文件描述符是3;当客户端连接服务器时,新建一个连接套接字,该文件描述符应该是4才对吧?但实际输出是5,为什么呢?求助大神!
服务器代码(图片):

客户端代码(图片):

服务器代码:
客户端代码:
测试结果:

服务器代码(图片):

客户端代码(图片):

服务器代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/epoll.h>
int init_server(const char *ipstr, unsigned short port, int backlog)
{
int s = socket(PF_INET, SOCK_STREAM, 0);
if(0 > s){
perror("socket");
return -1;
}
printf("s = %d\n", s);
struct sockaddr_in addr = {
.sin_family = PF_INET,
.sin_port = htons(port),
.sin_addr = {
.s_addr = ((ipstr == NULL) ? INADDR_ANY : inet_addr(ipstr)),
},
};
memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
socklen_t len = sizeof(addr);
if(0 > bind(s, (struct sockaddr*)&addr, len)){
perror("bind");
return -1;
}
if(0 > listen(s, backlog)){
perror("listen");
return -1;
}
return s;
}
int add_event(int efd, int fd, unsigned int event)
{
struct epoll_event evt;
evt.events = event;
evt.data.fd = fd;
return epoll_ctl(efd, EPOLL_CTL_ADD, fd, &evt);
}
int del_event(int efd, int fd, unsigned int event)
{
struct epoll_event evt = {
.events = event,
.data = {
.fd = fd,
},
};
return epoll_ctl(efd, EPOLL_CTL_DEL, fd, &evt);
}
int main()
{
int s = init_server(NULL, 9999, 3);
if(0 > s){
return -1;
}
int efd = epoll_create(1);
if(0 > efd){
perror("epoll_create");
return -1;
}
if(0 > add_event(efd, s, EPOLLIN)){
perror("add_event");
return -1;
}
printf("Wait for a new comming ...\n");
#define MAX 1024
struct epoll_event evts[MAX];
int timeout = -1;
while(1){
int ret = epoll_wait(efd, evts, MAX, timeout);
if(0 > ret){
perror("epoll_wait");
break;
}else if(0 == ret){
printf("\tTimeout.\n");
continue;
}
int i;
for(i = 0; i < ret; i++){
if(s == evts[i].data.fd){
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
socklen_t len = sizeof(addr);
int rws = accept(s, (struct sockaddr*)&addr, &len);
if(0 > rws){
perror("accept");
close(s);
return -1;
}
printf("client %d :ip[%s]:port[%u]\n",
rws, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
if(0 > add_event(efd, rws, EPOLLIN)){
perror("add_event fail ");
close(rws);
}
}else{
char buf[MAX];
memset(buf, 0, MAX);
int num = recv(evts[i].data.fd, buf, MAX-1, 0);
if(0 >= num){
printf("id = %d, client %d leave.\n", i, evts[i].data.fd);
if(0 > del_event(efd, evts[i].data.fd, EPOLLIN))
perror("del fd");
close(evts[i].data.fd);
}else{
printf("socket[%d], RECV[%dbytes]:%s\n",
evts[i].data.fd, num, buf);
}
}
}
}
}
客户端代码:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
char *ipstr = "127.0.0.1";
unsigned short port = 9999;
if(argc == 3){
ipstr = argv[1];
port = atoi(argv[2]);
}
int c = socket(PF_INET, SOCK_STREAM,0);
if (c < 0){
perror("socket");
return -1;
}
struct sockaddr_in addr = {
.sin_family = PF_INET,
.sin_port = htons(port),
.sin_addr.s_addr = inet_addr(ipstr),
.sin_zero = {0},
};
if(connect(c, (struct sockaddr *)&addr,
sizeof(addr)) < 0){
perror("connect");
return -1;
}
int id = 0;
#define MAX 1024
char buf[MAX];
int size;
while(1){
snprintf(buf, MAX, "NO.%d: hello world", id++);
size = strlen(buf);
if (0 >= send(c, buf, size, 0)){
printf("Send fail!\n");
break;
}
printf("send: [%dbytes]: %s\n", size, buf);
sleep(1);
}
close(c);
return 0;
}
测试结果:

...全文
相关推荐
epoll使用详解
在linux的网络编程中,很长的时间都在使用select来做事件触发。在linux新的内核中,有了一种替换它的机制,就是epoll。 相比于select,epoll最大的好处在于它不会随着监听fd数目的增长而降低效率。因为在内核中的select实现中,它是采用轮询来处理的,轮询的fd数目越多,自然耗时越多。并且,在linux/posix_types.h头文件有这样的声明: #define __FD_SETSIZE 1024 表示select最多同时监听1024个fd,当然,可以通过修改头文件再重编译内核来扩大这个数目,但这似乎并不治本。
149 Linux 网络编程5 ,netstat -apn 命令,改动文件描述符的上限,高并发服务器 --多路I/O转接服务器 - epoll ,ET/LT,epoll反应堆
其中8000为端口号。
linux 网络编程 epoll 高效IO
linux平台服务器网络编程 epoll 模型 代码测试通过
Linux网络通信epoll模型
本程序以简单的例子介绍了Linux中epoll的用法
linux下使用epoll基于socket套接字的通信库。.zip
linux下使用epoll基于socket套接字的通信库。.zip


