Всем доброго здоровия! Помогите начинающему понять что к чему. Задача-примитив. Накропал код, который читает строку из файла. Все работает, но только один раз! Почему? Код (Text): #include "stdafx.h" #include <stdio.h> #include <winsock.h> ////////////////////// #pragma comment(lib, "ws2_32.lib") WSADATA wsa_data; SOCKET s; sockaddr_in addr; hostent* hn; ////////////////////////// int len, szf, a, b, c, cp; char serverName[512]; char serverParam[512]; char serget[1280]; char BufLoad[1492]; char BuffBig[512]; char BuferHead[1490]; char BuffRes[512]; bool zatvor=false; //////////////////////////////// bool BuffCompare( char* buff1, char* buff2, int nn) { for(int i=0;i<nn;i++) { if(buff1[i]!=buff2[i])return(false); } return(true); } /////////// void Run(char *file_name) { lstrcpy(serverName,"vb-man.narod.ru"); lstrcpy(serverParam,file_name); lstrcpy(serget,"GET /");// ///////////////////////////// lstrcat(serget,serverParam); lstrcat(serget," HTTP/1.0\r\nHost: "); lstrcat(serget,serverName); lstrcat(serget,"\r\nUser-Agent: ClientDownloader\r\nAccept: text/html\r\nConnection: close\r\n\r\n"); ///////////////////////////// WSAStartup(0x0202,&wsa_data); s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); hn=gethostbyname(serverName); addr.sin_family=AF_INET; addr.sin_port=htons(80); addr.sin_addr.S_un.S_addr=*(DWORD*)hn->h_addr_list[0]; connect(s,(LPSOCKADDR)&addr,sizeof(addr)); send(s,serget,lstrlen(serget),0); RtlZeroMemory(BufLoad,1492); RtlZeroMemory(BuffBig,sizeof(BuffBig)); /////////////////////////////////////// do { len = recv(s,BufLoad,1492,0); for(cp=0;cp<len;cp++) { BuffBig[szf]=BufLoad[cp];// szf++; } RtlZeroMemory(BufLoad,1492);// if(len==SOCKET_ERROR) { closesocket(s); WSACleanup(); goto Error; } } while(len>0); closesocket(s); WSACleanup(); /////////////// a=0; c=0; RtlZeroMemory(BuferHead,sizeof(BuferHead)); RtlZeroMemory(BuffRes,sizeof(BuffRes)); for(a=0;a<szf;a++)// { if((zatvor==false)&&(BuffBig[a]==0x0d)&&(BuffBig[a+1]==0x0a)&&(BuffBig[a+2]==0x0d)&&(BuffBig[a+3]==0x0a)) { zatvor=true; BuferHead[a]=0x00; a=a+4; } switch(zatvor) { case true: BuffRes[c]=BuffBig[a]; c++; break; case false: BuferHead[a]=BuffBig[a]; break; } } BuffRes[c]=0; ///////////////// if(BuffCompare(BuffRes,"Start",5)) printf("Start\n"); else printf("Not Start string\n"); Error: return; } //////////////////////////////// void main(void) { Run("proba.txt"); Sleep(1000); Run("proba.txt"); /////// return; } Заранее благодарен за конструктивнуюю критику.
Хотел пояснить. Консольное приложение лезет по адресу http://vb-man.narod.ru/proba.txt и читает из файла строку "Start". Если строка другая, то об этом сообщает. Ждет секунду и повторяет вызов. И со второго раза не может прочитать строку. Подскажите в чем засада.
Ну помогайте, профи! Только начал изучать сокеты, ну совершенно непонятно как работает структура WSADATA. Возможно надо WSADATA очищать перед вторым вызовом или полностью закрывать соединение каким-то образом? В каком направлении рыть хоть?
Если прочитать это, отпадает куча вопросов Например, там написано, что WSAStartup достаточно вызвать один раз при запуске.
ПВСMSW тут не причём =) подозреваю что у тебя чтото со следующими переменными len, szf, a, b, c, cp; (1. они глобальные, 2. ... собственно поэтому )
Благодарю, замечание полезное в плане оптимизации кода. Действительно достаточно один раз объявить структуру. Просто вынес объявление WSAStartup и WSACleanup за пределы функции: Код (Text): void main(void) { WSAStartup(0x0202,&wsa_data); Run("proba.txt"); Sleep(1000); Run("proba.txt"); WSACleanup(); }
По ходу возникли вопросы по инициализации массивов. Чтобы не открывать новую тему может быть здесь кто-нибудь ответит. Парни, подскажите пожалуйста: - чем(каким символом) лучше(корректнее) инициализировать 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. Только не посылайте в гугл...
После инициализации память области которую занимает массив может быть заполнена одним из 256 значений. Т.е. байт может принимать значения от 0х00 и до 0хFF.(поправьте если я ляпнул чего-то не того) Возник глобальный вопрос из соображений "пассивной безопастности"(ну типа на всякий пожарный)-чем заполнять? Вот и подумалось что существуют определенные рекомендации профи на этот счет. 2)memset - понятненько, я то же склонялся к использованию этой функции, спасибо за ликбез.
э, так профи где ж их найти... ну есть наверное смысл переменную инициализировать если будешь использовать дальше. и чем инициализировать это тебе решать в зависимости от того какого поведения ты хочешь от своей программы. то есть если char i; while(i<10){} то cкорее всего что и надо и скорее всего нолем. а если char i; while(i){} то вполне может быть и чем то отличным от ноля. а если char i; i = SomeFunctionResult; то зачем оно вообще надо инициализировать?
Код (Text): char n[1]={""}; 1. Не делай так никогда! 2. Инициализация зависит от логики. Если ты используешь переменную до инициализации то студия выдаст варнинг об этом. О чем собственно и говорилось. Безопасность здесь непричём.
Почему? Если можно поподробней. Я написал так: 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 и там было объяснение о его целесообразности, но, к сожалению, уже не вспомню что к чему.
потому что char i[1] <- массив из одного элемента. Зафига такой массив? Переменные используй, они для этого и предназначены. Итого твоя запись будет эквивалентна Код (Text): char i =0; Компилятор так инициализирует только глобальные переменные. Локальные переменные будут содержать муссор так как создаются в стеке в момент выполнения программы.
HiroProtagonist Вот простой пример Код (Text): #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { int i=0; return 0; } а вот тоже созданное компилятором Код (Text): int _tmain(int argc, _TCHAR* argv[]) { 009F1370 push ebp 009F1371 mov ebp,esp 009F1373 sub esp,0CCh 009F1379 push ebx 009F137A push esi 009F137B push edi 009F137C lea edi,[ebp-0CCh] 009F1382 mov ecx,33h 009F1387 mov eax,0CCCCCCCCh 009F138C rep stos dword ptr es:[edi] int i=0; 009F138E mov dword ptr [i],0 return 0; 009F1395 xor eax,eax } 009F1397 pop edi 009F1398 pop esi 009F1399 pop ebx 009F139A mov esp,ebp 009F139C pop ebp 009F139D ret