Пишу что то на подобии многопоточного IP сканера. И у меня возникла проблема. После следующего события. Я подключаюсь к хосту connect. send отправляю HTTP запрос на скачивание файла. читаю файл select 10 ожидание recv. Так вот если файл на хосте есть то всё в порядке. А вот если его нет, то я больше не могу выполнить connect. Я так понял что предидущее соединение осталось активным на созданном сокете, и поэтому не происходит коннест. пробовал вызвать shutdown перед коннектом, но тоже не работает. Подскажите как быть?
Как вариант нашёл решение: закрытие и создание нового сокета. Но мне кажется это как то не правильно. Хотя работает вроде бы
Код (Text): DWORD WINAPI ThreadProc( __in LPVOID lpParameter){ TThreadInfo *p=(TThreadInfo*)lpParameter; CHTTP *HTTP=new CHTTP(); char genhost[0x50]; long TempKey=p->ScanHost->Key; bool Status=true; while(Status){ while (HTTP->CheckInet()&&Status){//есть интернет EnterCriticalSection(&p->ScanHost->cs); long TempInd=p->index; printf("ind %d\n",TempInd); p->index++; LeaveCriticalSection(&p->ScanHost->cs); p->ScanHost->Rnd->gen_host(TempKey+TempInd,genhost); if (HTTP->Connect(genhost)){ HTTP->RequestGET((char*)PageSign); HTTP->Recv(); //HTTP->Disconnect(); if (HTTP->GetLen()>=(sizeof(PageID)-1)){ if (memcmp(HTTP->GetData(),(char*)PageID,sizeof(PageID)-1)==0){ p->Status=false; p->ScanHost->Key=TempKey+TempInd; strcpy(p->ScanHost->Host,genhost); } } } Status=p->Status; } if (Status) Sleep(30000); } delete HTTP; return TRUE; } bool CClientTCP::Connect(char *Host,int Port){ if (bConnect) Disconnect(); strcpy(this->Host,Host); this->Port=Port; sockaddr_in sa; sa.sin_family = AF_INET; hostent *ip=gethostbyname(Host); if (ip==0) return bConnect; sa.sin_addr.s_addr = *(DWORD*)(ip->h_addr_list[0]); sa.sin_port = htons(Port); if (connect(hSocket,(sockaddr*)&sa,sizeof(sa))==0) bConnect=true; return bConnect; }; bool CClientTCP::Send(char *buf,int len){ bool Status=false; if (!bSocket || !bConnect) return false; if (send(hSocket,buf,len,0)!=SOCKET_ERROR) Status=true; return Status; } int CClientTCP::Recv(char *buf,int len){ int Status=0; int iResult=0; if (!bSocket || !bConnect) return false; unsigned long am_bytes; fd_set fd_read; FD_ZERO(&fd_read); FD_SET(hSocket,&fd_read); timeval tv; tv.tv_sec=3; tv.tv_usec=0; int res=select(0,&fd_read,0,0,&tv); if (SOCKET_ERROR==res) return Status; if ((res!=0) && (FD_ISSET (hSocket, &fd_read))) iResult=recv(hSocket,buf,len,0); else iResult=0; if (iResult>0) Status=iResult; if (iResult==0) Status=-1; if (iResult<0) Status=0; return Status; } основные части выложил. Код (Text): fd_set fd_read; FD_ZERO(&fd_read); FD_SET(hSocket,&fd_read); timeval tv; tv.tv_sec=3; tv.tv_usec=0; int res=select(0,&fd_read,0,0,&tv); думаю тут что то нахимичил if (SOCKET_ERROR==res) return Status; if ((res!=0) && (FD_ISSET (hSocket, &fd_read))) так как были проблемы при отсутствии файла на сервере(ждал бесконечно) и при лишнем чтении recv
Код (Text): int Status=0; int iResult=0; if (!bSocket || !bConnect) return false; unsigned long am_bytes; fd_set fd_read; FD_ZERO(&fd_read); FD_SET(hSocket,&fd_read); timeval tv; tv.tv_sec=3; tv.tv_usec=0; int res=select(0,&fd_read,0,0,&tv); if (SOCKET_ERROR==res) return Status; if ((res!=0) && (FD_ISSET (hSocket, &fd_read))) iResult=recv(hSocket,buf,len,0); else iResult=0; if (iResult>0) Status=iResult; if (iResult==0) Status=-1; if (iResult<0) Status=0; Код работает. Но есть проблемка. При приёме любых данных в конце происходит таймаут 3 сек. Таймаут происходит так как код не может определить когда закончились пакеты, recv должен вернуть 0. Но получается так первый буфер 630 байт, он и последний должен быть. И потом ещё раз считывает. Но в сокете нет уже данных и выход происходит по таймауту. Как определить размер принимаемых данных?
fsd это мне надо смотреть поле Content-Length: ? Но ведь оно не всегда есть в заголовке. А если это не HTTP протокол, а просто посылается команда серверу, а он в ответ шлёт какие то данные. То тогда как быть?
ещё одно решение HTTP 1.0 Connection: Close и после последнего пакета соединение закрывается. и recv 0 возвращает. Но вот если что нибудь на другой стороне произойдёт и не произойдёт закрытия. повиснет же. Тоже не очень решение. T800 Так у меня же нет доступа к IP/TCP уровню. При использовании сокетов. хотя возможно я не знаю каких то основных принципов TCP/IP fsd не слышал раньше почитаю RFC