Чтение файла на сокетах. Чего не хватает или как правильно?

Тема в разделе "WASM.NETWORKS", создана пользователем vb_man, 19 сен 2009.

  1. vb_man

    vb_man New Member

    Публикаций:
    0
    Регистрация:
    19 сен 2009
    Сообщения:
    24
    Всем доброго здоровия!
    Помогите начинающему понять что к чему.
    Задача-примитив. Накропал код, который читает строку из файла. Все работает, но только один раз! Почему?
    Код (Text):
    1. #include "stdafx.h"
    2. #include <stdio.h>
    3. #include <winsock.h>
    4. //////////////////////
    5. #pragma comment(lib, "ws2_32.lib")
    6. WSADATA wsa_data;
    7. SOCKET s;
    8. sockaddr_in addr;
    9. hostent* hn;
    10. //////////////////////////
    11. int len, szf, a, b, c, cp;
    12. char serverName[512];
    13. char serverParam[512];
    14. char serget[1280];
    15. char BufLoad[1492];
    16. char BuffBig[512];
    17. char BuferHead[1490];
    18. char BuffRes[512];
    19. bool zatvor=false;
    20. ////////////////////////////////
    21. bool BuffCompare(   char* buff1,
    22.                     char* buff2,
    23.                     int nn)
    24. {
    25.     for(int i=0;i<nn;i++)
    26.     {
    27.         if(buff1[i]!=buff2[i])return(false);
    28.     }
    29.     return(true);
    30. }
    31. ///////////
    32. void Run(char *file_name)
    33. {
    34.     lstrcpy(serverName,"vb-man.narod.ru");
    35.     lstrcpy(serverParam,file_name);
    36.     lstrcpy(serget,"GET /");//
    37.     /////////////////////////////
    38.     lstrcat(serget,serverParam);
    39.     lstrcat(serget," HTTP/1.0\r\nHost: ");
    40.     lstrcat(serget,serverName);
    41.     lstrcat(serget,"\r\nUser-Agent: ClientDownloader\r\nAccept: text/html\r\nConnection: close\r\n\r\n");
    42.     /////////////////////////////
    43.     WSAStartup(0x0202,&wsa_data);
    44.     s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    45.     hn=gethostbyname(serverName);
    46.     addr.sin_family=AF_INET;
    47.     addr.sin_port=htons(80);
    48.     addr.sin_addr.S_un.S_addr=*(DWORD*)hn->h_addr_list[0];
    49.     connect(s,(LPSOCKADDR)&addr,sizeof(addr));
    50.     send(s,serget,lstrlen(serget),0);
    51.     RtlZeroMemory(BufLoad,1492);
    52.     RtlZeroMemory(BuffBig,sizeof(BuffBig));
    53.     ///////////////////////////////////////
    54.     do
    55.     {
    56.         len = recv(s,BufLoad,1492,0);
    57.         for(cp=0;cp<len;cp++)
    58.         {
    59.             BuffBig[szf]=BufLoad[cp];//
    60.             szf++;
    61.         }
    62.         RtlZeroMemory(BufLoad,1492);//
    63.         if(len==SOCKET_ERROR)
    64.         {
    65.             closesocket(s);
    66.             WSACleanup();
    67.             goto Error;
    68.         }
    69.     }      
    70.     while(len>0);
    71.     closesocket(s);
    72.     WSACleanup();
    73.     ///////////////
    74.     a=0;
    75.     c=0;
    76.     RtlZeroMemory(BuferHead,sizeof(BuferHead));
    77.     RtlZeroMemory(BuffRes,sizeof(BuffRes));
    78.     for(a=0;a<szf;a++)//
    79.     {
    80.         if((zatvor==false)&&(BuffBig[a]==0x0d)&&(BuffBig[a+1]==0x0a)&&(BuffBig[a+2]==0x0d)&&(BuffBig[a+3]==0x0a))
    81.         {
    82.             zatvor=true;
    83.             BuferHead[a]=0x00;
    84.             a=a+4;
    85.         }
    86.         switch(zatvor)
    87.         {
    88.             case true:
    89.                 BuffRes[c]=BuffBig[a];
    90.                 c++;
    91.                 break;
    92.             case false:
    93.                 BuferHead[a]=BuffBig[a];
    94.                 break;
    95.         }
    96.     }
    97.     BuffRes[c]=0;
    98.     /////////////////
    99.     if(BuffCompare(BuffRes,"Start",5))
    100.         printf("Start\n");
    101.     else
    102.         printf("Not Start string\n");
    103.     Error: return;
    104. }
    105. ////////////////////////////////
    106. void main(void)
    107. {
    108.     Run("proba.txt");
    109.     Sleep(1000);
    110.     Run("proba.txt");
    111.     ///////
    112.     return;
    113. }
    Заранее благодарен за конструктивнуюю критику.
     
  2. vb_man

    vb_man New Member

    Публикаций:
    0
    Регистрация:
    19 сен 2009
    Сообщения:
    24
    Хотел пояснить. Консольное приложение лезет по адресу http://vb-man.narod.ru/proba.txt и читает из файла строку "Start". Если строка другая, то об этом сообщает. Ждет секунду и повторяет вызов. И со второго раза не может прочитать строку. Подскажите в чем засада.
     
  3. vb_man

    vb_man New Member

    Публикаций:
    0
    Регистрация:
    19 сен 2009
    Сообщения:
    24
    Проехт(VS 6.0 ) на всякий пожарный в аттаче.
     
  4. vb_man

    vb_man New Member

    Публикаций:
    0
    Регистрация:
    19 сен 2009
    Сообщения:
    24
    Ну помогайте, профи!
    Только начал изучать сокеты, ну совершенно непонятно как работает структура WSADATA.
    Возможно надо WSADATA очищать перед вторым вызовом или полностью закрывать соединение каким-то образом?
    В каком направлении рыть хоть?
     
  5. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
  6. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    ПВСMSW тут не причём =) подозреваю что у тебя чтото со следующими переменными len, szf, a, b, c, cp; (1. они глобальные, 2. ... собственно поэтому )
     
  7. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    Забыл: в сокетах ошибку не ищи (пока что) =)
     
  8. vb_man

    vb_man New Member

    Публикаций:
    0
    Регистрация:
    19 сен 2009
    Сообщения:
    24
    Точно! ТщательнЕй надо! В szf оставлся старый индекс.
    Огромное СПАСИБОг!
     
  9. vb_man

    vb_man New Member

    Публикаций:
    0
    Регистрация:
    19 сен 2009
    Сообщения:
    24
    Благодарю, замечание полезное в плане оптимизации кода. Действительно достаточно один раз объявить структуру.
    Просто вынес объявление WSAStartup и WSACleanup за пределы функции:
    Код (Text):
    1. void main(void)
    2. {
    3.     WSAStartup(0x0202,&wsa_data);
    4.     Run("proba.txt");
    5.     Sleep(1000);
    6.     Run("proba.txt");
    7.     WSACleanup();
    8. }
     
  10. vb_man

    vb_man New Member

    Публикаций:
    0
    Регистрация:
    19 сен 2009
    Сообщения:
    24
    По ходу возникли вопросы по инициализации массивов. Чтобы не открывать новую тему может быть здесь кто-нибудь ответит.
    Парни, подскажите пожалуйста:
    - чем(каким символом) лучше(корректнее) инициализировать CHAR переменные?
    (По умолчанию компилятор(линковщик) VC 6.0 устанавливает (""), но на умолчание как известно надеятся нельзя.
    - какой функцией(VC 6.0) или способом правильней проводить инициализацию?
    Можно конечно пользоваться своей:
    ///////////////////
    void init_char_array(char arr[],
    int nn)
    {
    char n[1]={""};
    for(int i=0;i<nn-1;i++)
    {
    arr=n[0];
    }
    }
    .........................
    Может использовать для этой цели memcpy или подобные?
    ........................
    Кто как делает?

    P.S. Только не посылайте в гугл...
     
  11. jakimushka

    jakimushka New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2006
    Сообщения:
    43
    1. а что значит корректнее инициализировать? 0?
    2. memset?
     
  12. vb_man

    vb_man New Member

    Публикаций:
    0
    Регистрация:
    19 сен 2009
    Сообщения:
    24
    После инициализации память области которую занимает массив может быть заполнена одним из 256 значений.
    Т.е. байт может принимать значения от 0х00 и до 0хFF.(поправьте если я ляпнул чего-то не того)
    Возник глобальный вопрос из соображений "пассивной безопастности"(ну типа на всякий пожарный)-чем заполнять?
    Вот и подумалось что существуют определенные рекомендации профи на этот счет.

    2)memset - понятненько, я то же склонялся к использованию этой функции, спасибо за ликбез.
     
  13. jakimushka

    jakimushka New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2006
    Сообщения:
    43
    э, так профи где ж их найти...
    ну есть наверное смысл переменную инициализировать если будешь использовать дальше. и чем инициализировать это тебе решать в зависимости от того какого поведения ты хочешь от своей программы. то есть если
    char i;
    while(i<10){}
    то cкорее всего что и надо и скорее всего нолем. а если
    char i;
    while(i){}
    то вполне может быть и чем то отличным от ноля. а если
    char i;
    i = SomeFunctionResult;
    то зачем оно вообще надо инициализировать?
     
  14. HiroProtagonist

    HiroProtagonist New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2009
    Сообщения:
    9
    Код (Text):
    1. char n[1]={""};
    1. Не делай так никогда!
    2. Инициализация зависит от логики. Если ты используешь переменную до инициализации то студия выдаст варнинг об этом. О чем собственно и говорилось. Безопасность здесь непричём.
     
  15. vb_man

    vb_man New Member

    Публикаций:
    0
    Регистрация:
    19 сен 2009
    Сообщения:
    24
    Почему? Если можно поподробней.

    Я написал так: char i[1]=""; для примера. Мне это то же нравится, потому и спрашивал.
    Вопрос как раз и возник потому, что так по умолчанию инициализирует
    компилятор(или линковщик)VC 6.0. Чтобы убедиться в этом набросал простенький код:
    char j[1];
    void main(void)
    {
    char i[1]="";

    if(i[0]==j[0])
    printf(" i[0]==j[0] %c\n",j[0]);
    else
    printf(" i[0]!=j[0] %c\n",j[0]);
    }

    Как-то в литературе встречал инициализацию 0xFF и там было объяснение о его целесообразности,
    но, к сожалению, уже не вспомню что к чему.
     
  16. HiroProtagonist

    HiroProtagonist New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2009
    Сообщения:
    9
    потому что char i[1] <- массив из одного элемента. Зафига такой массив? Переменные используй, они для этого и предназначены. Итого твоя запись будет эквивалентна
    Код (Text):
    1. char i =0;
    Компилятор так инициализирует только глобальные переменные. Локальные переменные будут содержать муссор так как создаются в стеке в момент выполнения программы.
     
  17. vb_man

    vb_man New Member

    Публикаций:
    0
    Регистрация:
    19 сен 2009
    Сообщения:
    24
    Понятненько. Спасибо.
     
  18. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    HiroProtagonist
    Вот простой пример
    Код (Text):
    1. #include "stdafx.h"
    2.  
    3.  
    4. int _tmain(int argc, _TCHAR* argv[])
    5. {
    6.     int i=0;
    7.     return 0;
    8. }
    а вот тоже созданное компилятором
    Код (Text):
    1. int _tmain(int argc, _TCHAR* argv[])
    2. {
    3. 009F1370  push        ebp  
    4. 009F1371  mov         ebp,esp
    5. 009F1373  sub         esp,0CCh
    6. 009F1379  push        ebx  
    7. 009F137A  push        esi  
    8. 009F137B  push        edi  
    9. 009F137C  lea         edi,[ebp-0CCh]
    10. 009F1382  mov         ecx,33h
    11. 009F1387  mov         eax,0CCCCCCCCh
    12. 009F138C  rep stos    dword ptr es:[edi]
    13.     int i=0;
    14. 009F138E  mov         dword ptr [i],0
    15.     return 0;
    16. 009F1395  xor         eax,eax
    17. }
    18. 009F1397  pop         edi  
    19. 009F1398  pop         esi  
    20. 009F1399  pop         ebx  
    21. 009F139A  mov         esp,ebp
    22. 009F139C  pop         ebp  
    23. 009F139D  ret