8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

UDP 数据包到达错误套接字并带有 SO_REUSEPORT

batata 2月前

46 0

在 Linux 内核 4.19 中,我有两个 UDP 套接字,它们使用 SO_REUSEPORT 绑定到同一个本地地址。我还将一个套接字(使用 connect(2))连接到远程地址,另一个套接字连接到远程地址。

使用 SO_REUSEPORT 绑定到 。我还将 连接 到远程地址,另一个套接字未 连接 。让远程套接字始终向本地发送消息。

我想要的现象是数据总是被已经连接的套接字接受。 但实际情况是,根据两个套接字的创建顺序,当先创建连接的套接字,后创建未连接的套接字时,数据总是发送到后创建的套接字(没有连接)。当创建顺序颠倒时,数据总是发送到先创建的套接字(有连接)。 这是一个错误吗?

在 Linux 内核 5.15 中,无论套接字的创建顺序如何,数据始终通过 connect 发送到套接字。 这正是我希望的。

运行以下代码程序将始终打印:listenfd recv

例子 :

#include<iostream>
#include<string.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <thread>
using namespace std;

int listenfd = 0, connfd = 0, clientfd = 0, efd;
int server_port = 6666, client_port = 5555;
char server_ip[] = "127.0.0.1", client_ip[] = "127.0.0.1";

void setFd(int fd, int property){
    int sockopt = 1;
    setsockopt(fd, SOL_SOCKET, property, (void* )&sockopt, sizeof(sockopt));
}
void setNonBlock(int fd) {
    int flags = fcntl(fd, F_GETFL, 0);
    int r = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
void updateEvents( int fd, int events, int op) {
    struct epoll_event ev;
    memset(&ev, 0, sizeof(ev));
    ev.events = events;
    ev.data.fd = fd;
    int r = epoll_ctl(efd, op, fd, &ev);
}

void addEvent(int fd) {
    updateEvents(fd, EPOLLIN, EPOLL_CTL_ADD);
}

void delEvent(int fd) {
    updateEvents(fd, EPOLLIN, EPOLL_CTL_DEL);
}

void startfd(int &fd, struct sockaddr_in& bind_addr, struct sockaddr_in& conn_addr,  bool conn) {
    if(fd) {
        delEvent(fd);
        close(fd);
        fd = 0;
    }

    fd = socket(AF_INET, SOCK_DGRAM, 0);
    setFd(fd,SO_REUSEADDR);
    setFd(fd,SO_REUSEPORT);
    setNonBlock(fd);
    
    int r = ::bind(fd, (struct sockaddr *)&bind_addr, sizeof(struct sockaddr));

    if(conn) {
        connect(fd , (struct sockaddr * )&conn_addr, sizeof(struct sockaddr));
    } 
    addEvent(fd);
}

void e_loop() {
    for(;;) {
        const int kMaxEvents = 20;
        struct epoll_event activeEvs[100];
        int n = epoll_wait(efd, activeEvs, kMaxEvents, 10000);

        for (int i = 0; i < n; i++) {
            int fd = activeEvs[i].data.fd;
            int events = activeEvs[i].events;
            if (events & (EPOLLIN | EPOLLERR)) {
                char s[10];
                int recv_n = recv(fd, s, 10, 0);
                if(fd == listenfd) {
                    cout << "listenfd recv\n";
                } else if(fd == connfd) {
                    cout << "connfd recv\n";
                }
            }
        }
    }
}

int main() {
    efd = epoll_create(1);
    thread t(e_loop);

    struct sockaddr_in caddr, saddr;
    memset(&caddr, 0, sizeof caddr);
    memset(&saddr, 0, sizeof saddr);
    caddr.sin_family = AF_INET;
    saddr.sin_family = AF_INET;
    caddr.sin_port = htons(client_port);
    saddr.sin_port = htons(server_port);
    caddr.sin_addr.s_addr = inet_addr(client_ip);
    saddr.sin_addr.s_addr = inet_addr(server_ip);

    startfd(connfd, saddr, caddr, true);
    startfd(listenfd, saddr, caddr,  false);
    startfd(clientfd, caddr, saddr,  true);

    while(1) {
        getchar();
        send(clientfd, "", 0, 0);
    }
}
帖子版权声明 1、本帖标题:UDP 数据包到达错误套接字并带有 SO_REUSEPORT
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由batata在本站《sockets》版块原创发布, 转载请注明出处!
最新回复 (0)
  • s3c 2月前 0 只看Ta
    引用 2

    我知道 ng-pattern 可用于允许字符。我正在寻找一种方法来限制一个特定的字符。我的输入框应该可以使用除竖线 '|' 之外的任何字符。我想要

    我知道 ng-pattern 可用于允许字符。我正在寻找一种方法来仅限制一个特定字符。

    我的输入框应该支持除竖线 '|' 之外的任何字符。我想抛出错误,但不允许输入。有没有简单的方法可以不允许输入该特定字符。或者我应该只使用 ng-pattern 来包含除竖线之外的所有内容?(我该怎么做?)

    我的html:

                         <td class="col-xs-3">
                            <input type="text"
                                  name="Application"
                                  ng-model="list.Application"
                                  maxlength="64"
                                  required />
    
                               <div ng-messages="addForm.Application.$error"
                                     ng-if="addForm.$submitted"
    
                            </div>
                        </td>
    

    enter image description here

  • 我如何使用 ng-pattern 来完全禁止竖线?这是否意味着我必须使用 ng-pattern 来允许除竖线之外的所有可能的字符?有没有更好的方法?

  • @WiktorStribiżew 我不知道任何正则表达式。我应该使用什么正则表达式来允许除 | 之外的所有内容?

  • 您需要添加一个 ng-pattern attribute input 使用正则表达式来限制文本输入。

    此正则表达式必须与文本匹配,因此,您需要检查完整输入是否没有管道符号。

    你需要:

    • ^ - 字符串的开始
    • [^|]* - 零个或多个除 | (替换 * + 以禁止空输入)
    • $ - 字符串结束。

    因此,使用

    ng-pattern="/^[^|]*$/"
    

    这些 /.../ 正则表达式分隔符会让 angular 知道我们正在传递一个正则表达式对象而不是字符串。

    此外, ng-pattern="[^|]*" 由于字符串模式在 Angular 中默认是固定的,因此也应该可以工作。

返回
作者最近主题: