Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > Нестабильный обмен данными


Автор: Mark4545 9.9.2007, 19:26
После обмена служебной инфой между клиентом и сервером(сокс5) , идет передача запрашиваемой инфы вот тут то и возникли проблемы.
Код

DWORD WINAPI DataTrans(LPVOID lParam)
{
    SOCKET AThreadS=Accept;//connected broweser
    SOCKET DThreadS=Distanse;//Connected to smth.
    unsigned long state=1;
    ioctlsocket(AThreadS,FIONBIO,(unsigned long*)&state);
    ioctlsocket(DThreadS,FIONBIO,(unsigned long*)&state);
    FD_SET ReadSet;
    int ReadySock;
      FD_ZERO(&ReadSet);
      FD_SET(AThreadS,&ReadSet);
      FD_SET(DThreadS,&ReadSet);
      select(0,&ReadSet,NULL,NULL,NULL);
   while(true)
    {
      char c[1]={0};
      int size=0;  
      size=recv(AThreadS,c,1,0);
      if(size!=0)
      {
          send(DThreadS,c,1,0);
      }
      
      size=recv(DThreadS,c,1,0);
      if(size!=0)
      {
         send(AThreadS,c,1,0);
      }
    }
    return 1;
}

Какой день уже думаю что не так.

Автор: W4FhLF 9.9.2007, 19:56
Ну во-первых, в чём смысл передавать по 1 байту? Пусть фрагментацией занимаются более низкие уровни, прикланой уровень этого касаться не должен. Во-вторых ты уверен, что блокирующий режим(синхронный) устанавливается верно? И, наконец, что значит нестабильный?

Автор: Mark4545 9.9.2007, 20:28
Блокирующий устанавливаеться верно например если делать так.
Код

char c[1024]={0};
recv(AThreadS,c,1024,0);
send(DThreadS,c,1024,0);
recv(DThreadS,c,1024,0);
send(AThreadS,c,1024,0);
recv(AThreadS,c,1024,0);
send(DThreadS,c,1024,0);
recv(DThreadS,c,1024,0);
// И так далее.
//Страницы грузяться нормально

В чем заглючаеться не стабильность.Заглючаеться в том что в браузер может попадать мусор
Хеддеры http протокола,может непрально передавать запросы.
Чем больше размер страницы запрашиваемой тем больше шанс на мусор разный или на плохой запрос.
Конечно бывают и удачные запросы редко(и когда страниы мелкие очень).

Автор: Mark4545 9.9.2007, 21:29
Стал боллее подробно расматривать все запросы, смотрю появляються например вот такая фигня
....
smth Right Headers.
....
....
ost:1.ru//Поидее должен быть Host:1.ru естесно 

Это частный пример одного запроса,куда девалась в данном случае буква H непонятно

Автор: yar 9.9.2007, 21:56
Попробуйте сделать размер буфера 2
Код

char c[2]={0};

При этом оставив в send и recv 1.

Возможно, происходит переполнение.
В этом можно убедиться, взглянув в отладчике на содержимое c.

Автор: Mark4545 9.9.2007, 22:11
Решил проблему обнулением массивов,после того как size==0

Добавлено через 6 минут и 25 секунд
Тем возникла еще одна проблемка)
Код представленый ниже,по какой то причине не пашет,но если раскоментировать мессадж боксы то пашет все ок.
В чем трабла?
Код

DWORD WINAPI DataTrans(LPVOID lParam)
{
     SOCKET AThreadS=Accept;//connected broweser
     SOCKET DThreadS=Distanse;//Connected to smth.
     unsigned long state=1;
     ioctlsocket(AThreadS,FIONBIO,(unsigned long*)&state);
     ioctlsocket(DThreadS,FIONBIO,(unsigned long*)&state);
     FD_SET ReadSet;
     int ReadySock;
      FD_ZERO(&ReadSet);
      FD_SET(AThreadS,&ReadSet);
      FD_SET(DThreadS,&ReadSet);
      select(0,&ReadSet,NULL,NULL,NULL);
      char c[1024]={0};
      int size=0;
      int count=0;
      while(1)
      {
        //MessageBox(0,"While",0,0);
        size=recv(AThreadS,c,1024,0);
        if(size>0)
        {
            send(DThreadS,c,1024,0);
            //MessageBox(0,c,"size1>0(Browser send to server)",0);
            count=0;
        }
        else
        {
            ZeroMemory(c,1024);
            //MessageBox(0,c,"size1<=0",0);
            count=count+1;
        }
        size=recv(DThreadS,c,1024,0);
        if(size>0)
        {
            send(AThreadS,c,1024,0);
            //MessageBox(0,c,"size2>0(Server to browser)",0);
            count=0;
        }
        else
        {
            ZeroMemory(c,1024);
            //MessageBox(0,c,"size2<=0",0);
            count=count+1;
        }
        if(count>=4)
        {
            //MessageBox(0,"exit",0,0);
            ExitThread(0);
        }    
      }
    return 1;
}


Добавлено через 11 минут и 57 секунд
а если например заменить все мессадж боксы секундным слипом  то тогда пашет гуд но страницы большие грузит оч долго.

Автор: yar 10.9.2007, 06:54
Решение может заключаться в использовании многопоточности.  Один поток читает из Accept сокета и пишет в Distanse, второй читает из Distanse и пишет в Accept.

Автор: W4FhLF 10.9.2007, 07:43
Цитата(Mark4545 @  9.9.2007,  22:11 Найти цитируемый пост)
Код представленый ниже,по какой то причине не пашет,но если раскоментировать мессадж боксы то пашет все ок.


Я собственно поэтому и спросил, установил ли ты блокирующий режим правильно? Видимо, нет. У тебя программа пытается считать из сокета данные, которые туда ещё не пришли. Решается проблема просто, есть функция select, которая может проверять возможность чтения данных из массива сокетов. Вот её и используй. 

Автор: 040375 11.9.2007, 20:45
Так он её и использует, только на мой взгляд неправильно. какой смысл в использовании ioctlsocket, если используется select?  
Какой смысл в использовании вызова select вне цикла? Ведь этот вызов устанавливает и считывает флаги состояния сокетов. Каждый раз после завершения операции чтения/записи в дескриптор нужно снова вызывать select - чтобы определить - какие данные готовы к отправке - а какие пришли в буфер для чтения. А в чего желать от такого кода - непонятно. Я под виндой не работаю, но select и прочее - что называется winsock2 в винде - из BSD - всё похоже.

Автор: Mark4545 12.9.2007, 20:19
да там селект полностью непрально использовано.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)