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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Нужна помощь по сокетам  (Прочитано 7791 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
alex87
Постоялец

ru
Offline Offline
Пол: Мужской

« : 01-04-2009 06:34 » 

Ситуация такая: обьявляется сокет для прослушивания порта(любого)
первый вариант:
Код:
int error;
char buff[6500];
  WSADATA wsaData;
  error=WSAStartup(MAKEWORD( 2, 0 ), &wsaData);
  if (error==SOCKET_ERROR)
     {
       Memo1->Lines->Add("произошла ошибка");
       WSACleanup();
     }
  else
      {
        Memo1->Lines->Add("Инициализация прошла");
      }
  sockaddr_in sock;
  sock.sin_family = AF_INET;
  sock.sin_port = htons(port);
  sock.sin_addr.s_addr = htonl(INADDR_ANY);
  int serv = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  if (serv == SOCKET_ERROR)
    {
      Memo1->Lines->Add("Ошибка в сокете");
      WSACleanup();
    }
  else
      Memo1->Lines->Add("Сокет ок");

  error = bind(serv, (sockaddr*)&sock,sizeof(sock));
  if (error == SOCKET_ERROR)
     Memo1->Lines->Add("Ошибка в bind");
  else
      {
        Memo1->Lines->Add("bind успешен");
        memset(buff,0,strlen(buff));
        int fromlen = sizeof(sock);
        int  rc = recvfrom(serv,buff,sizeof(buff),0,(sockaddr *)&sock,&fromlen);
        if (rc==SOCKET_ERROR)
             Memo1->Lines->Add("ошибки");
         else
             Memo1->Lines->Add(buff);
      }
Программа зависает до получения пакета, одного в данном случае(потом будет цикл, while ), как сделать, чтоб этого не было?
Надо использовать асинхронный сокет т.е.  WSAAsyncSelect()
Но вот беда: параметр wMsg1 как описать в нем?
Второй  вариант:
есть функция обьявляю в хендл
Код:
public:
 ....
 void __fastcall WMUserN ( TMessage& Msg );
protected:
BEGIN_MESSAGE_MAP
  MESSAGE_HANDLER(WM_USER + 1, TMessage, WMUserN);
END_MESSAGE_MAP(TForm);
потом
Код:
void __fastcall WMUserN ( TMessage& Msg )
{
  char buff[65000];
  int fromlen = sizeof(sockaddr_in);
  int lent=sizeof(buff);
  int rev_lent=0;
  sockaddr_in sock;
  sock.sin_family = AF_INET;
  sock.sin_port = htons(port);
  sock.sin_addr.s_addr = htonl(INADDR_ANY);
  int serv = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  if (serv != SOCKET_ERROR)
  {
  while (rev_lent < lent)
       {
         WSAAsyncSelect(serv,Handle,sizeof(buff),FD_READ);
         int rr= recvfrom(serv,buff,lent-rev_lent,0,(sockaddr *)&sock,&fromlen);
         if (rr==SOCKET_ERROR)
            ShowMessage("Ошибка");
         else
             {
               Memo1->Lines->Add(buff);
               rev_lent +=rr;
             }

       }
  }
  else
     ShowMessage("все плохо");
}
Как это дело связать с сокетом? Код правильно ли я написал?
Потом еще будет дорабатываться до отправления сообщения.
« Последнее редактирование: 05-04-2009 16:40 от Ghost » Записан

Улыбаюсь Ага
alex87
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 06-04-2009 04:55 » 

решил проблему, кому интересно выложу код Улыбаюсь
пошел по второму вырианту
в хендел:
Код:
public:
void __fastcall WMUserN (TMessage & msg);
protected:
   BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(WM_USER+1, TMessage, WMUserN);
   END_MESSAGE_MAP(TForm)
сам код в сср
Код:
void __fastcall TForm1::WMUserN (TMessage & msg)
{
//обработчик приходящего сообщения
  TDateTime DateTime = TDateTime::CurrentDateTime();
  char buf[6500];
  AnsiString a,IpAddr,port_iz,date_N;
  int j=0;
  j=sizeof(buf);
  int nLen;
  struct sockaddr_in from;
  int nLength=sizeof(struct sockaddr_in);
  switch (WSAGETSELECTEVENT(msg.LParam))
        {
          case FD_READ:
               {
                 nLen=recvfrom(serv,buf,j,0,(struct sockaddr*)&from,&nLength);
                 if(nLen>0)
                    {
                      date_N=DateTime.DateTimeString();
                      IpAddr = inet_ntoa (from.sin_addr );
                      port_iz = htons(from.sin_port);
                      Memo1->Lines->Add("Дата прилета: " + date_N);
                      Memo1->Lines->Add("Адрес отправителя: " + IpAddr + "\r\n" + "Порт: "+ port_iz);
                      buf[nLen]='\0';
                      a="Длинна сообщения:"+AnsiString(nLen)+"\r\n"+StrPas(buf);
                      Memo1->Lines->Add(a);
                    }

               }
        }

}
Записан

Улыбаюсь Ага
Rulik
Помогающий

ru
Offline Offline

« Ответ #2 : 26-05-2009 18:59 » 

1. можно использовать простой select
2. можно сокет перевести в неблокирующий режим и читать в цикле, ну или когда удобно.
Записан
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #3 : 26-05-2009 19:15 » 

Rulik, фигасе какие люди, теме уже больше месяца Улыбаюсь Тем более что чел решил вроде проблему.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines