Хотел бы оценить сравнение между двумя структурами sockaddr_in
В настоящее время я занимаюсь созданием архитектуры одноранговой сети и нахожусь на этапе создания функции получения, которая будет принимать сообщения от нескольких клиентов в сети. По сути, когда вызывается функция recvfrom - адрес самого последнего клиента, который отправил сообщение основному клиенту, загружается в структуру sockaddr_in, называемую fromAddr. Затем программа предназначена для цикла по вектору, содержащему несколько экземпляров класса клиента (каждый из которых содержит необходимую информацию и функциональные возможности для представления клиента в сети), и поиска экземпляра клиента, структура sockaddr_in которого совпадает с таковой для только что полученного сообщение. В программе на данный момент эвакуация выглядит так:
void UDPClass::checkID(Message* mess, sockaddr_in fraeAddress)
{
sockaddr_in anAddr;
//Iterate through the vector of clients and find the one who sent the message
for(int i = 0; i<theClients.size(); i++)
{
anAddr = theClients[i].getAddress();
//if the address of the recieved message matches the address of the current client
if((anAddr.sin_addr == fraeAddress.sin_addr) && (anAddr.sin_port == fraeAddress.sin_port))
{
//Update local instance of the client so that its location data matches that of the recieved message
theClients[i].setX(mess->x);
theClients[i].setY(mess->y);
}
}
}
Когда программа скомпилирована, появляется следующая ошибка:
Ошибка 3 ошибка C2678: двоичный файл "==": не найден оператор, который принимает левый операнд типа "IN_ADDR" (или нет приемлемого преобразования)
Как можно заключить, я также попытался оценить выражение, просто сравнив две структуры sockaddr_in:
if(anAddr == fraeAddress)
Который сообщает ту же ошибку. Вопрос заключается в следующем: если не считать создания класса sockaddr_in с перегруженными операторными функциями, который позволил бы вам оценить выражение, каков был бы самый простой способ реализации этого сравнения?
2 ответа
Вы можете проверить неподписанные длинные члены in_addr следующим образом:
if((anAddr.sin_addr.s_addr == fraeAddress.sin_addr.s_addr) && (anAddr.sin_port == fraeAddress.sin_port))
или для Windows:
if((anAddr.sin_addr.S_addr == fraeAddress.sin_addr.S_addr) && (anAddr.sin_port == fraeAddress.sin_port))
В зависимости от того, как именно происходят ваши адреса, бывают случаи, когда сравнение байтов не сработает: адреса IPv4 могут храниться либо в sockaddr_in
или же sockaddr_in6
, sockaddr_in6
может содержать или не содержать sin6_scope_id
а также sin6_flowinfo
и выравнивание может варьироваться.
Вам нужны только IPv4 и IPv6, или вам нужны другие типы сокетов? (В наши дни писать программы только для IPv4 непростительно.) Если это так (и, возможно, даже если вам нужно поддерживать типы сокетов unix, netlink, raw или неясные сокеты), я рекомендую преобразовать все IP-адреса в IPv6 и затем использовать ваш собственный класс для сравнения.
(Также не следует использовать линейный поиск).