- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我遇到了以下问题:我有一个接收连接的 epoll 代码:
while (1) {
int nfds = epoll_wait(epollfd, events, 4096, -1);
if (nfds == -1) {
if (errno == EINTR)
continue;
perror("epoll_wait");
exit(EXIT_FAILURE);
}
for (int i = 0; i < nfds; i++) {
if (events[i].data.fd == server_sock) {
client_sock = accept(server_sock,
(struct sockaddr *)&client_name,
(socklen_t *)(&client_name_len));
if (client_sock == -1) //server overloaded
continue;
ev.events = EPOLLIN | EPOLLERR;
#ifdef CORE_NONBLOCKING_SOCKETS
Arch::set_nonblocking(client_sock);
ev.events |= EPOLLET; //input data and connection closing
#endif
#ifdef EPOLLRDHUP
ev.events |= EPOLLRDHUP ;//
#else
//for old libraries
ev.events |= EPOLLHUP;//
#endif
ev.data.fd = client_sock;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, client_sock, &ev) == -1) {
perror("epoll_ctl: client_socket");
exit(EXIT_FAILURE);
}
accept_request(client_sock);
} else {
#ifdef EPOLLRDHUP
if (events[i].events & EPOLLRDHUP) {
std::cout << "EPOLLRDHUP on " << events[i].data.fd << std::endl;
listener->disconnectDriver(events[i].data.fd);
}
#else
if (events[i].events & EPOLLHUP) {
std::cout << "EPOLLHUP on " << events[i].data.fd << std::endl;
listener->disconnectDriver(events[i].data.fd);
}
#endif
if (events[i].events & EPOLLIN) {
std::cout << "debug EPOLLIN on " << events[i].data.fd << std::endl;
accept_request(events[i].data.fd);
}
if (events[i].events & EPOLLERR) {
std::cout << "debug EPOLLERR on " << events[i].data.fd << std::endl;
listener->disconnectDriver(events[i].data.fd);
}
}
}
当我收到输入连接时,我试图读取所有 buff 数据:
void get_all_buf(int sock, std::string & inStr) {
int n = 1;
int total = 0;
char c;
char temp[1024*1024];
bzero(temp, sizeof(temp));
do {
#ifdef CORE_NONBLOCKING_SOCKETS
timespec time_to_wait;
time_to_wait.tv_nsec = 10000000;
time_to_wait.tv_sec = 0;
timespec tm;
time_t begin = time(NULL);
do {
#endif
n = recv(sock, &temp[total], sizeof(temp), 0);
#ifdef CORE_NONBLOCKING_SOCKETS
nanosleep(&time_to_wait, &tm);
time_t end = time(NULL);
if ((end - begin) > MAX_CLIENT_TIME) {
inStr = std::string();
return;
}
} while (n < 0 && errno == EAGAIN); //nonblocking sockets in edge-triggered mode
#endif
if (n > 0) {
total += n;
} else if (n == 0) {
//TODO: error handling
//debug
std::cout << "possibly no one byte was received" << std::endl;
break;
} else if (n < 0) {
//TODO: error handling
//debug
std::cout << "error while receiving data" << std::endl;
if (errno == EBADF) {
std::cout << "recv returns with EBADF: " << strerror(errno) << std::endl;
} else if (errno == EFAULT) {
std::cout << "recv returns with EFAULT: " << strerror(errno) << std::endl;
} else if (errno == EINTR) {
std::cout << "recv returns with EINTR: " << strerror(errno) << std::endl;
} else if (errno == EINVAL) {
std::cout << "recv returns with EINVAL: " << strerror(errno) << std::endl;
}
//end debug
break;
}
} while (!strstr(temp, "</packet>"));
inStr = temp;
};
在 accept_request
函数中。但有时我的调试输出如下:
packet type='connect'
size of vector<Driver> in getDriversWithMoney is 1
epoll_wait detected activity of 164 counter i = 0 nfds = 1
EPOLLRDHUP on 164
disconnectDriver (fd = 164)
driver 1 disconnected
debug EPOLLIN on 164
error while receiving data
recv returns with EBADF: Invalid file descriptor
这意味着某人首先连接而不是断开连接,当他尝试再次连接时 recv
返回 EBADF
。我做错了什么?请帮助我。
P.S. EPOLLRDHUP
我只是关闭文件描述符。 epoll
man 说没问题,因为 epoll
自己从 epoll_wait
队列中移除关闭的 fd。
最佳答案
当远程主机关闭套接字时,epoll()
报告文件描述符的 HUP
和 EPOLLIN
。
首先检查EPOLLRDHUP
,然后关闭套接字;然后检查 EPOLLIN
,也找到它,然后尝试调用 recv()
。由于套接字已关闭,文件描述符不再有效,您将得到 EBADF
(已关闭的套接字已从 epoll
集合中移除,所以后续 epoll_wait()
调用不会返回它;但是对于已经返回的 epoll_wait()
来说为时已晚 - EPOLLIN
已经在您的 events[i]
中等待。
您需要在调用 disconnectDriver()
后停止检查事件(如果它关闭了文件描述符):
if (events[i].events & EPOLLRDHUP) {
std::cout << "EPOLLRDHUP on " << events[i].data.fd << std::endl;
listener->disconnectDriver(events[i].data.fd);
continue;
}
关于linux - EBADF while recv after epoll_wait,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4895581/
所以我正在阅读一本过时的小书(2010 年),我正在尝试使用 Linux 系统调用复制一个文件。这就是我所拥有的: 注意:忽略tlpi_hdr.h和error_functions.h,它们定义了err
无法清除输出流:java.net.SocketException:关闭失败:EBADF(错误文件编号) 有没有人得到这个,有没有解决这个异常的方法? 最佳答案 这可能意味着您没有写入该文件的权限或者它
我的程序有问题,它正在使用 IPC 消息队列。虽然 IPC 工作正常,但管道存在问题,我还无法解决。这是我程序的子进程代码。它从文件中读取一个字节,然后将其写入管道。 char buf; int
我遇到了以下问题:我有一个接收连接的 epoll 代码: while (1) { int nfds = epoll_wait(epollfd, events, 4096, -1); i
如果我像 50 reload/10 seconds 这样多次重新加载我的应用程序(从带有重新加载按钮的浏览器),它会给我这个错误: events.js:45 throw arguments[1
我已经搜索过相关问题,但没有找到。我创建了一个显示图片、名称和地址的 InfoWindowMarker。然后我创建 OnInfoWindowClickListener,它将显示所选标记的纬度和经度。但
我正在开发一个在两个进程之间进行IPC调用的程序。我使用socketpair创建两个套接字fd: int fds[2] = {-1,-1}; if (socketpair(AF_LOCAL, SOCK
我正在尝试修复调用 select() 的事件循环中的错误。当 select() 返回 EBADF 时,会记录一个错误,然后重新初始化 fd 集并再次调用 select。这会导致日志记录的无限硬循环,在
我们的生产代码中存在一个长期存在的错误。这本质上是一个基于套接字的守护进程。它使用 select 监听一堆文件描述符。 偶尔(大约一天一次),select 将返回 EBADF。 我已经编写了代码来搜索
我的 VS 代码在使用 git 时开始变得 super 慢,而且我经常在使用 EBADF 时看到错误,无论是在搜索文件还是使用 git 时。 我看到磁盘可能不可用。我有 Mac Pro 2020。这是
由于 CVE 导致我们将应用程序升级到 Rails 4.1.12 和 Rack 1.5.5,我们似乎随机出现 502。大约 1% 的请求,我不能始终如一地重新创建问题,只能观察它(这非常令人沮丧,你可
我尝试使用 Node.js 处理一个 500MB 的 Apache 日志文件,将其语法从 ip.ip.ip.ip - - [02/Aug/2012:05:01:17 -0600] "GET /path
我有一个代码,我在其中使用 select() 函数调用来轮询添加到 readfds 集的套接字列表,用于任何传入数据。 while(1) { ret = select(n,&readfds,N
当我尝试将外部存储的一个文件复制到文件夹数据库时,会发生此错误: java.io.IOException: read failed: EBADF (Bad file number) 这个错误发生在这个
我是 Hadoop 的新手,尝试使用 Hadoop 编写关系连接。该算法尝试在连续两轮中连接三个关系。我使用递归方法。该程序运行良好。但是在执行期间它会尝试打印这样的警告: 14/12/02 10:4
我有这个错误 java.io.IOException: read failed: EBADF (Bad file number) 在这行代码中: while ((input = fis.read(b
希望大家指出我明显的错误; 系统是嵌入式linux,代码是c语言 我们在cgi脚本中有一些代码,它接受来自(Boa)网络服务器的STDIN_FILENO数据流(文件上传)并将其写入临时文件(“/tmp
尝试写入 RandomAccessFile 时,我收到 java.io.IOException: write failed: EBADF(错误文件描述符)。 RandomAccessFile
程序运行到getsockname,返回-1,errno为9(EBADF,错误的文件描述符)。但是,Android 应用程序中检测的代码运行良好。 void sysLibCSendHookHandler
我对制作简单的 .xls 文件并将数据写入一个单元格的脚本有疑问。这是简单的代码: require 'spreadsheet' class Filter def filter @excel
我是一名优秀的程序员,十分优秀!