- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
ioctl() 将套接字更改为异步模式。根据手册页上的定义,当套接字上可以进行 I/O 时,内核会发送 SIGIO。我已经使用测试客户端运行了这个,并且 I/O 正常(数据包到达源和目的地),那么为什么内核不调用 sigpoll?
澄清一下,问题在于,尽管已经建立了 SIGIO 信号并占用了套接字来发送信号 SIGIO,但没有信号触发,也没有迹象表明 sigpoll() 被调用。
我已经上传了发现此问题的代码,它最终将成为谈话的一些淡化版本。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <setjmp.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/signal.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/in.h>
#define MAX_BUF 1000
#define CHAR_BUF 50
#define BASEPORT "10000"
void error(const char *msg){
perror(msg);
exit(1);
}
typedef struct tuple{
char HN [MAX_BUF];
char PN [MAX_BUF];
}tuple;
tuple storeCMD( char input[]){
tuple ret;
char* token = strtok(input, " ");
if (token != NULL) strcpy( ret.HN, token);
else ret.HN[0] = 0;
token = strtok(NULL, " ");
if (token != NULL) strcpy( ret.PN, token);
else ret.PN[0] = 0;
return ret;
}
void sigpoll(int sig){
printf("Signal fired!\n");
//eventual rcvfrom and other things...
}
int main(int argc, char * argv[]){
if (argc != 2){
printf("Proper usage requires 2 arguments: $talkish port-number\n");
exit(1);
}
int sd;
struct sockaddr_storage client;
socklen_t clientLen;
struct addrinfo server, *res;
struct addrinfo *serverinfo;
char buffer [MAX_BUF];
memset(&server, 0, sizeof(server));
bzero((char *) &server, sizeof(server));
server.ai_family = AF_INET;
server.ai_socktype = SOCK_DGRAM;
server.ai_flags = AI_PASSIVE;
//initially we'll use information from user, but move to partner and partnerl
//once solid connection is established.
struct sockaddr_storage partner;
socklen_t partnerl;
//Bind to argv[1]
tuple execute;
getaddrinfo(NULL, argv[1], &server, &res);
sd = socket(res -> ai_family ,res -> ai_socktype, res -> ai_protocol);
if (sd < 0) error("ERROR on socket!");
int n = bind(sd, res -> ai_addr, res -> ai_addrlen);
if (n < 0) error("ERROR on Bind!");
int flag;
flag= 1;
fcntl(sd, F_SETOWN, getpid());
signal(SIGPOLL, sigpoll); //establish sigpoll to get udp packets
ioctl(sd, FIOASYNC, &flag);
//establish timer to allow wait and see
struct timeval timer;
timer.tv_sec = 7;
//while connecting
char message[CHAR_BUF];
bzero((char *) message, CHAR_BUF);
int connecting = 1;
while(connecting){
printf ("? ");
scanf(" %[^\n]", message);
if (strlen(message) == 0);
else if ( 0 == strcmp( message, "q")){
exit (0);
}
else {
execute = storeCMD(message);
if (execute.HN[0] == 0 || execute.PN[0] == 0) printf("| Input should match \"Hostname Portname\" to connect and \"q\" to quit \n");
else {
struct sockaddr_storage dest_server;
socklen_t dest_serverl;
struct addrinfo dest_hints, *dest_res;
struct in_addr dest_addr;
memset(&dest_hints, 0, sizeof(dest_hints));
dest_hints.ai_family = AF_INET;
dest_hints.ai_socktype = SOCK_DGRAM;
dest_hints.ai_flags = AI_PASSIVE;
if (getaddrinfo( execute.HN, execute.PN, &dest_hints, &dest_res) < 0) printf("| Input should match \"Hostname Portname\" to connect and \"q\" to quit \n");
else {
bzero((char *) buffer, MAX_BUF);
sprintf(buffer, "wannachat");
sendto(sd, buffer, MAX_BUF, 0, (struct sockaddr *) dest_res -> ai_addr, dest_res -> ai_addrlen );
if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &timer, sizeof(timer)) < 0) error("ERROR on setsockopt");
partnerl = sizeof(partner);
bzero((char *) &partner, partnerl);
bzero((char *) buffer, MAX_BUF);
if (recvfrom(sd, buffer, MAX_BUF, 0, (struct sockaddr *)&partner, &partnerl ) < 0) printf("| No response received from %s. \n", execute.HN);
else{
if ( 0 == strcmp( buffer, "OK")){
printf("| Connected to %s. \n", execute.HN);
//chat();
}else printf("| %s does not want to talk. \n", execute.HN);
}
}
}
}
}
close(sd);
return 0;
}
最佳答案
要接收 SIGIO 通知(对于套接字也是 SIGURG,例如:当接收 TCP URG 数据时),您需要告诉内核要通知谁,使用 fcntl(fd, F_SETOWN, pid)
。通常,正的 pid 值指的是一个进程,而负的 pid 值指的是一个进程组。
在 Linux 上,如果要将信号发送到特定线程,则需要使用 F_SETOWN_EX
。在其他系统上,您必须阻止其他线程上的信号。使用pthread_sigmask()
.
关于c - SIGIO从不开火,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40334670/
我想编写一个程序,在 SIGIO 上向线程池中的所有线程发出信号。我编写了以下代码,但似乎一个套接字一次只能由一个线程拥有,因此只会向线程池中的最后一个线程通知事件。有没有什么方法可以让我在不使用专用
我正在尝试接收串行数据,但我无法确定时间。 当接收到串行数据时,SIGIO 何时触发 - 在接收到数据的第一个字节时,还是在接收到特定字符(CR、NL...)时? 设置串行数据端口: /* Open
根据我的研究,您可以添加一个 epoll 文件描述符来轮询、选择或另一个 epoll,如果事件可用,它将返回 POLLIN。根据 epoll(7): Q3 Is the epoll file
这有点长...对于初学者,我使用的是 Linux 2.6.33,gcc 4.4.4。 我写了一个小程序,它创建一个命名管道并读取它,直到它看到一个特定的字符串,然后它摆脱 FIFO,并重新执行自己。
当文件描述符上可以进行 I/O 时,我尝试接收信号。程序在不执行 I/O 时需要执行其他操作,因此不宜使用 select(2)。 当我运行下面的示例代码时,即使标准输入上没有数据,它也会尽可能快地从处
我正在处理的 C++ 程序中遇到与 SIGIO 相关的问题。 平台:Linux 2.6.30,x86 Arch 场景:异步串行通信。 我关注了this async-communication exam
我编写了一个程序,该程序正在读取和写入一些 gpio 引脚,并使用数据报连接通过套接字接收一些数据。当收到 SIGIO 信号时,我想尝试从套接字读取数据。但是当我尝试这样做时,gpio 引脚上的读/写
在工作中,有人要求我在 Linux 上使用 C++ 为工业硬件实现一个新的 Controller 应用程序。一个关键特性是在使用 modbus 的设备之间使用 radio 调制解调器通信。我能够很好地
我正在实现一个客户端和服务器,它们使用sendto() 和recvfrom() 通过UDP 进行通信。我想在从服务器接收数据时为我的客户端使用 SIGPOLL 。我的问题是,在处理程序中,另一个信号到
我需要为 Linux 平台下的病人监护子系统创建一个 JNI c 库。我必须通过 USB 串行端口读取数据并写入命令。只要端口打开,设备就会以不同的频率和大小连续发送多种类型的数据。 在 Java 中
我正在尝试在文件描述符上可以进行 I/O 时接收信号。该程序在不执行 I/O 时需要执行其他操作,因此不能使用 select(2)。 当我运行下面的示例代码时,它会尽可能快地从处理程序内部打印消息,即
我正在学习 C 中的信号。我正在尝试编写一个符合 POSIX 和 ANSI 标准的程序。我希望我的程序在发生某些事情时发出信号,但 SIGIO 不是 POSIX 并且 SIGPOLL 在 POSIX
首先,当数据准备好读取时,我无法让串行设备生成 SIGIO。 我正在尝试编写一个简单的串行接口(interface),以使用 USB 转串行适配器与微型计算机进行通信。我想让这个接口(interfac
我正在使用 SIGIO 构建一个 UDP 非阻塞客户端和服务器套接字对,以促进服务器上数据的接收。这是我的情况。当客户端向我发送消息时,我会激活 SIGIO。然而,这些消息大约是。 3 个 1024
我在带有回调的异步模式下使用 ALSA (snd_async_add_pcm_handler())。每个 ALSA 的回调都是从 SIGIO 信号处理程序调用的。每个回调调用我的函数getCurren
我是一名优秀的程序员,十分优秀!