【发布时间】:2020-09-04 13:00:29
【问题描述】:
我正在尝试使用 poll 实现 UDP-UART 桥接器。该程序工作正常,但我认为 POLLIN 事件是在我收到东西时触发的,但当我发送东西时也会触发......
fds[0].fd = port; // configure fdset 0 on uart
fds[0].events = POLLIN ; // we are interested by POLLIN events type
fds[1].fd = socket; // configure fdset 1 on udp socket
fds[1].events = POLLIN ; // we are interested by POLLIN events type
while(1) // main process loop
{
ret = poll(fds,2, timeout_msecs); // check the two fds for events (uart & socket)
if (ret > 0) { // if there is an event
if (fds[1].revents & POLLIN) // if the event is an input on socket fds[1]
{
sock_length = recvfrom(socket,&sock_buff,sizeof(sock_buff),MSG_WAITALL, (struct sockaddr *) &servaddr, &fromlen); //receive from socket and store tosock_buff
write(port,sock_buff,sock_length); // send back sock_buff content through uart
}
if (fds[0].revents & POLLIN) // if the event is an input on uart fds[0]
{
ser_length = read(port, ser_buff, sizeof(ser_buff) ); //read the uart and store to serbuff
sendto(socket,ser_buff,ser_length,MSG_CONFIRM, (const struct sockaddr *) &servaddr,sizeof(servaddr)); //send the serial buffer via udp socket
}
}
else // if nothing append before "timeout_msecs" milliseconds (5000)
{
printf("timeout \n");
}
这是我的代码,我遇到的问题如下: 假设我在 uart 端得到了一些东西,例如“hello server”,然后我使用 sendto 通过套接字发送字符串。但我认为它会触发套接字上的 POLLIN 事件。所以它会在 uart 中写回我刚刚发送的数据,就像一个回声......
当我发送“hello server”时,我想在 uart 中返回服务器“hello client”的答案
但目前我得到“hello server hello client”,因为套接字 POLLIN 事件被触发了两次,当我发送时,以及当服务器应答时
当我使用“sendto”时,有没有办法防止 POLLIN 被触发?
最好的问候,
皮埃尔。
编辑:套接字以这种方式初始化:
struct sockaddr_in servaddr;
int open_connection(char * IPaddr,unsigned int port)
{
int sockfd = 0;
if (( sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 )
{
perror("socket creation failed");
return -1;
}
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port);
servaddr.sin_addr.s_addr = inet_addr(IPaddr);
return sockfd;
}
【问题讨论】:
-
请记住
poll会修改您传递的数组中的结构,并且您需要在每次调用之前重置它。 -
还要记住
ret可能是-1,以防出错(除了超时,ret将为零)。 -
@Someprogrammerdude
poll()仅修改revents。您无需重置任何内容。 -
servaddr是如何初始化的?请提供更多代码上下文,如果代码可用,恕我直言无法解释行为。 -
你在调试器中观察到了吗?