Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Классы и их использование - не могу ДАЖЕ вопрос точно задать. :((  (Прочитано 9872 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Mitia
Гость
« : 04-08-2005 14:00 » 

Помогите разобраться с С++

Описание класса:
Код:
class myNet
{
public:
SOCKET sd;
struct sockaddr_in addr;
SOCKET s;
long rc;
SOCKADDR_IN _addr;
SOCKADDR_IN remoteAddr;
char buf[256];
 
bool CreateBroadcastServer(int port);
bool sendBroadcast();
};

Также имеем реализации функций класса myNet для UDP:
Код:
#include "network.h"
#include <stdio.h>

//нужно ли в программе указывать еще и SOCKET ?
bool myNet::CreateBroadcastServer(int port)
{
  WSADATA wsa;
  WSAStartup(MAKEWORD(2,2),&wsa);
  memset(buf,0,strlen(buf));

     s=socket(PF_INET,SOCK_DGRAM,0);
     if(s==INVALID_SOCKET)
     {...}

   char n=1;
   rc = setsockopt(s,SOL_SOCKET,SO_BROADCAST,&n,sizeof(BOOL));
   if (rc==SOCKET_ERROR)
   {
      printf("Error setting options %d\n",WSAGetLastError());
      closesocket(s);
        WSACleanup;
    //  exit(1);
   }
    _addr.sin_family=PF_INET;
   _addr.sin_addr.s_addr = INADDR_BROADCAST;
   _addr.sin_port=htons(port);

   return true;
}

bool myNet::sendBroadcast()
{
rc=sendto(s,"Test Message Broadast",strlen("Test message"),0,(SOCKADDR*)&_addr,sizeof(SOCKADDR_IN));
   
if(rc==SOCKET_ERROR)
   {    printf("Error send, error code: %d\n",WSAGetLastError());
rc=WSAGetLastError();
switch(rc)
{
case WSANOTINITIALISED: printf(" 1 "); break;
case WSAENETDOWN: printf(" 2 "); break;
case WSAEINTR: printf(" 3 "); break;
case WSAEINPROGRESS: printf(" 4 "); break;
case WSAENOTSOCK: printf(" 5 "); break;
case WSAEWOULDBLOCK: printf(" 6 "); break;
default: break;
}
   }
closesocket(s);
WSACleanup;
     return true;
}


Пишем две программы:

Первая запускается, но не отсылает ничего – говорит, что WSAENOTSOCK (при отсылке):
Код:
#include

// Указатель на класс. По идее можно и просто “myNet acceptServer;” – есть ли большая разница? Я второй сервер создаю точно также. 
myNet * acceptServer=0;

int main()
{
//выделяем память под наш объект
myNet * acceptServer = new myNet;
//создаем сервер
acceptServer->CreateBroadcastServer(5002);

//пытаемся отправить слово..., но дает ошибку WSAENOTSOCK. В дебаггере видно, что все данные структуры SOCKADDR_IN не заполнены, ПОЧЕМУ???
while(1)
{
acceptServer->sendBroadcast();
}

return 0;
}


ВАРИАНТ, КОТОРЫЙ ВЫВАЛИВАЕТСЯ С ОШИБКОЙ ЧТЕНИЯ ПАМЯТИ при отсылке – также в дебаггере видно, что ничего не определено:

Код:
 
myNet * acceptServer=0;

void prerun()
{
myNet * acceptServer = new myNet;
acceptServer->CreateBroadcastServer(5002);
}
 

int main()
{
prerun();
acceptServer->sendBroadcast();
return 0;
}

Ошибок во время инициализации вроде как не вылазит никаких.

Может есть ссылки на статьи или главы книг, где можно понять, почему так??? Если не сложно, то буду благодарен за разъяснения. Заранее спасибо.
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 04-08-2005 19:45 » 

Я до конца не разбирался. Но не понял, а вообше с кем ты хочеш соединить сокет. У тебя я не видел второй точки, с кем ты хочеш соединится.
Код:
   _addr.sin_family=PF_INET;
   _addr.sin_addr.s_addr = INADDR_BROADCAST;
   _addr.sin_port=htons(port);

   return true;
Вот здесь наверно должна еше идти функция connect, после заполнения структуры.
Вот тут почитай курс молодого бойца по сокетам https://club.shelek.ru/view.php?id=29
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Mitia
Гость
« Ответ #2 : 04-08-2005 20:00 » 

Цитата
Вот здесь наверно должна еше идти функция connect, после заполнения структуры.
Вот тут почитай курс молодого бойца по сокетам https://club.shelek.ru/view.php?id=29

Вроде как читал, но другие туториалы. Без использования класса все работает - рутер за 10 сек вылетает Улыбаюсь)
Еще вопрос по ходу(уже сетевой) - почему Outpost начинает показывать отсчет отосланных байт спустя достаточно длительное время?
У меня UDP и Connect'а быть не должно.
Я собственно сижу и не могу понять, правильно ли я сделал, что в ветку по С++ запостил, т.к. во всех примерах в принципе также, только все по функциям разбито. Может в этом какие-то грабли?

Еще вопрос, если я хочу делать много клиентов на основе класса, то мне создавать указатели и выделять память или создавать объекты так:  myNet _client1. В чем разница?
« Последнее редактирование: 20-12-2007 19:46 от Алексей1153++ » Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #3 : 04-08-2005 20:13 » 

Код:
myNet * acceptServer=0;

void prerun()
{
myNet * acceptServer = new myNet;
acceptServer->CreateBroadcastServer(5002);
}


int main()
{
prerun();
acceptServer->sendBroadcast();
return 0;
}
Здесь ты перемудрил. В сях есть такое понятие  "Зоны видимости". В функции prerun переменная acceptServer и то что ты ее объявил глобально, это разные веши. Если ты в функции запишеш так  acceptServer = new myNet; т.е. без объявления еше раз, то у тебя класс должен заработать.  Пока я не говорю про сам сокет.
« Последнее редактирование: 04-08-2005 20:30 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #4 : 04-08-2005 20:52 » 

Еше маленький прикол
Код:
while(1)
{
acceptServer->sendBroadcast();
}
У тебя здесь бесконечный цикл. Но в sendBroadcast у тебя сокет закрывается после отсылки. Естественно вторая попытка отсылки выдаст тебе ошибку.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #5 : 04-08-2005 21:05 » 

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

Не будите спашяго дракона.
             Джаффар (Коша)
Mitia
Гость
« Ответ #6 : 05-08-2005 11:10 » new

вот же ж... какой раз уже на подобные грабли (два раза myNet *) наступал... думаю, этот раз уже запомню надолго Улыбаюсь)

Все остальное тоже понял... так элементарно все... наверное, магнитные бури у нас Ага

Спасибо.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines