在向量上找到第一对元素(int)并获得第二个(struct)

Posted

技术标签:

【中文标题】在向量上找到第一对元素(int)并获得第二个(struct)【英文标题】:find first pair element (int) on a vector and get second (struct) 【发布时间】:2016-04-04 15:19:27 【问题描述】:

已解决。见下文 我正在运行这样的服务:

int pgsService::startService(int sockfd)
    listen(sockfd,5);
    int c = accept(sockfd, (struct sockaddr *)&cli_addr,&clilen);
    clients.push_back(std::make_pair(sockfd,cli_addr));
    std::cout << "Accepted:" << c << "\tIP:" << inet_ntoa(cli_addr.sin_addr) << std::endl;
    return c;

构造函数:

pgsService::pgsService(int *fd,int port) 
    bzero((char *) &serv_addr, sizeof(serv_addr));
    *fd = socket(AF_INET,SOCK_STREAM,0);
    assert(*fd>0);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port=htons(port);
    bind(*fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
    clilen = sizeof(cli_addr);

私人会员:

private:
        struct sockaddr_in serv_addr, cli_addr;
        int sfd;
        socklen_t clilen;
        std::vector<std::pair<int, struct sockaddr_in> > clients;
;

CompareFirst 结构体:

struct CompareFirst

  CompareFirst(int val) : val_(val) 
  bool operator()(const std::pair<int,struct sockaddr_in>& elem) const 
    return val_ == elem.first;
  
  private:
    int val_;
;

启动绑定本地端口的服务实例。 此端口将用于 .NET 客户端应用程序中的类似聊天的服务,但服务器端我在 C++ 中执行所有操作。

所以,在我pgsService server = pgsService(&amp;sockfd,port); 之后,我打电话给int client = server.startService(sockfd); 如上所述。 构造函数仅在将结构等设置为套接字服务器时绑定。 有连接时: 仅测试代码

write(client,hello.c_str(),hello.length());
void *buf = malloc(512);
memset(buf,0,512);
read(client,buf,512);
std::cout << "From:" << inet_ntoa(server.getClientInfo(client).sin_addr) << ":"<< server.getClientInfo(client).sin_port << "\t - " << (char*)buf << std::endl;
free(buf);
shutdown(client,2);
exit(0);

输出如下:

$ ./pgs_service
Accepted:4      IP:127.0.0.1
GETING:0.0.0.0
GETING:0.0.0.0
From:0.0.0.0:0   - LOL

我正在尝试将客户数据信息保存在一个向量中:

clients.push_back(std::make_pair(sockfd,cli_addr));

getClientInfo 方法是:

struct sockaddr_in pgsService:: getClientInfo(int client)
    std::vector< std::pair <int, struct sockaddr_in> >::iterator it = std::find_if(clients.begin(),clients.end(),CompareFirst(client));
    std::cout << "GETING:" << inet_ntoa(it->second.sin_addr) << std::endl;
    return (it->second);

所以我存储在接受另一个 std::pair 类型对象的客户端向量中。 我推入堆栈,当我需要获取结构时,我只需调用 getClientInfo 并使用 find_if 找到它。 问题是我相信返回值不是实际的结构,因为它有时会返回一些整数,例如: 83.0.0.0 然后 0.0.0.0 然后 30.0.0.0 。似乎我正在访问我不应该访问的内存区域,幸运的是程序没有崩溃。

我做错了什么?在哪里?我认为这是我推入向量的方式或我获取数据的方式。

解决方案:当我 push_back 时,我用 sockfd 制作“make_pair”,但我不应该这样做。我必须按“c”。

【问题讨论】:

cli_addr 在哪里初始化? 在构造函数中。将编辑问题。 您编辑的帖子仍未初始化或声明 cli_addr。我假设您正在其他地方这样做。 你是说在课堂上?第二次编辑... 【参考方案1】:

我在这里假设了很多事情。

    您在某处定义了 CompareFirst。 后续调用之间 到startService 我假设你正在将内存设置cli_addr0

我认为您使用向量和 std::pair 构造在配对后填充向量方面没有任何根本性的错误。然而,诀窍可能是确保语义正确性。在接受退货后,您能否检查cli_addr 实际上是否正确填充?

另外,不是推送服务器 fd,您不应该推送接受返回的 fd - 在您的情况下为 c? IMO,完成您正在做的事情的更好方法是使用关联数据结构,如地图或无序地图。此外,为了更好的设计,您应该评估诸如 select 之类的机制来处理 i/o,因为您的 accept 调用实际上会阻塞。

还有一个问题是没有检查 find_if 的返回值。您应该始终将迭代器与 clients.end() 进行比较,以确保它是有效的迭代器。

希望这会有所帮助。

【讨论】:

我到达了向量的末尾。看来我找不到 fd... :/ 你能再检查一下 CompareFirst 是否正常吗? CompareFirst 不是问题,make_pair 中的第一个应该是 c 而不是 sockfd。

以上是关于在向量上找到第一对元素(int)并获得第二个(struct)的主要内容,如果未能解决你的问题,请参考以下文章

使用整数向量的向量对整数向量进行基数排序

如何根据对的第二个元素对对的向量进行排序?

在c ++中给出两个整数向量(相同的大小和类型),我想从最小到最大的元素对一个进行排序并更改第二个向量的顺序[重复]

[算法]冒泡排序

冒泡排序

如何使用 R 在向量中找到第二个非连续出现的值的索引?