2015-03-20 9 views
0

В настоящее время я занимаюсь разработкой одноранговой сетевой архитектуры и нахожусь на стадии создания функции приема, которая будет принимать сообщения от нескольких клиентов в сети. По сути, когда вызывается функция recvfrom - адрес последнего клиента, отправившего сообщение основному клиенту, загружается в структуру sockaddr_in, называемую fromAddr. Затем программа предназначена для прокрутки вектора, содержащего несколько экземпляров класса клиента (каждый из которых содержит необходимую информацию и функциональные возможности для представления клиента в сети) и найти экземпляр клиента, структура sockaddr_in которого соответствует только что полученному сообщение. В программе evaulation в данный момент выглядит так:Хотел бы оценить сравнение двух sockaddr_in structs

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); 
    } 
} 
} 

Когда программа составлена ​​следующая ошибка сообщается:

Error C2678 3 ошибки: двоичный «==»: ни один оператор не найден, который принимает левого -hand операнда типа «in_addr» (или нет приемлемого преобразования)

Как можно было сделать вывод, я также попытался оценить выражение, просто сравнивая два sockaddr_in структур себя:

if(anAddr == fraeAddress) 

Который сообщает ту же ошибку. Возникает вопрос: не удалось ли создать класс sockaddr_in с перегруженными функциями оператора, которые позволили бы вам оценить выражение, каким будет самый простой способ реализации этого сравнения?

+0

Похоже, что ['memcmp()'] (http://en.cppreference.com/w/c/string/byte/memcmp) поможет вам. Просто сравнение указателей типа 'if (anAddr == fraeAddress)' не очень помогает. –

+1

Перегрузка оператора – arynaq

ответ

4

Вы можете проверить неподписанные длинные члены 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)) 
+0

Спасибо - очевидно, много переменных содержится в структуре in_addr, но будет сравнивать переменные ulong каждого in_addr, сравнивая фактический IP-адрес, - я подозреваю, что IP-адрес содержится в переменных 4 uchar. Хотя я дам вам метод. – Enchanter

+0

Эти четыре uchar находятся в союзе с ulong (Microsoft), поэтому unsigned long занимает то же место, что и они. – DNT

0

В зависимости от того, как именно ваши адреса происходят, есть случаи, когда байт -соединение не будет работать: адреса IPv4 могут быть сохранены либо в sockaddr_in, либо в . может содержать или не содержать sin6_scope_id и sin6_flowinfo, и выравнивание может отличаться.

Вам нужны только IPv4 и IPv6, или вам нужно обращаться с другими видами сокетов? (В наши дни непростительно писать программы с поддержкой только IPv4.) Если да (и, возможно, даже если вы должны сделать, необходимо поддерживать типы unix, netlink, raw или неясный сокет), я рекомендую преобразовать все IP-адреса в IPv6, а затем используя свой собственный класс для сравнения.

(Также вы не должны использовать линейный поиск).

+0

Эта структура является чисто академическим упражнением, поэтому в этом случае не обязательно использовать IPv6, но в любом случае спасибо. Несмотря на то, что поиск является линейным, я намереваюсь, в конечном итоге, получить функцию, выполняющуюся на поток все свои собственные. – Enchanter

+0

@ Исчезновение в чисто академическом упражнении еще более важно делать все правильно.И это плохой дизайн для использования one-thread-per-socket, в большинстве случаев вам нужен один-на-процессор для балансировки нагрузки. – o11c

+0

О, согласитесь, важно, чтобы все было правильно, если не использовать один поток для каждого сокета - по одному потоку для каждой функции - как в одной функции, итерации по всем клиентам и посылке пакетов обновления к ним непрерывно, так и одному потоку, получающему пакеты, и обновлению локально сохраненных клиентов соответственно и непрерывно. И, вероятно, лучше иметь один поток на ядро ​​- один поток на процессор подразумевает один поток в целом - у вас есть один процессор, содержащий много ядер, способных одновременно запускать поток. – Enchanter