PDA

Просмотр полной версии : setsockopt непонятная проблема


_nic
18.11.2009, 22:14
Использую setsockopt для таймаута в случае с recv(чекаю прокси).Проблема в том что в большинстве случаев recv висит до конца таймаута, но если приконектится к тому же проксику без setsockopt то recv получает данные в пределах таймаута :confused:
ВОт код:

DWORD WINAPI check(LPVOID lParam)
{
/*WSADATA wsd;
WSAStartup(MAKEWORD(2,2),&wsd);*/
char Ip[30],msg[100]=" ";
char *port=new char[30];
char *indata=new char[1024*256];
memset(indata,NULL,1024*256);
char *result=new char[1024*256];
memset(result,NULL,1024*256);
SOCKADDR_IN adr;
struct timeval timeout;
ZeroMemory(&timeout,sizeof(timeval));
timeout.tv_sec= 9;
SOCKET s;
ZeroMemory(&adr,sizeof(adr));
for(int i=0;i!=Form1->ListBox1->Count;i++)
{
strcpy(Ip,Form1->ListBox1->Items->operator [](i).c_str());
strcpy(port,Form1->ListBox1->Items->operator [](i).c_str());
strtok(Ip,":");
port+=strlen(Ip)+1;
adr.sin_family=AF_INET;
adr.sin_addr.s_addr=inet_addr(Ip);
adr.sin_port=htons(atoi(port));
WSASetLastError(0);
s=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeval));
connect(s,(sockaddr*)&adr,sizeof(adr));
send(s,msg,100,0);
Form1->Memo1->Lines->Add("1\r");
recv(s,indata,1024*256,0);
Form1->Memo1->Lines->Add("2\r");
Form1->Memo1->Lines->Add("Count:"+AnsiString(i)+"\r");
//wsprintf(result,"Proxy: %s:%s\rAnswer:\r%s\rSocketError: %d",Ip,port,indata,WSAGetLastError());
//Form1->Memo1->Lines->Add(result);
strtok(indata,"\r\n\r\n");
Form1->Memo1->Lines->Add(AnsiString(indata)+"\r");
if(strstr(indata,"200")!=NULL)
{
Form1->ListBox2->Items->Add(AnsiString(Ip)+":"+AnsiString(port));
}
port-=strlen(Ip)+1;
closesocket(s);
memset(result,NULL,1024*256);
memset(indata,NULL,1024*256);
}
//WSACleanup();
return(0);
}

Если коротко то проблема в том что recv нереагирует на появивщиеся данные в сокете и таймаут тикает до конца :(

slesh
19.11.2009, 10:44
какое-то у тебя неадекватное время таймаута стоит. Оно задается на в секундах а в миллисекундах.

struct timeval timeout = {0}
...........
timeout.tv_sec = 10000; // 10 секунд
...........
setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(struct timeval));


А вообще в коде чтото не вижу проверок на валидность сокета. Т.е. ты не проверяещ - создался он или нет.
также нет проверки того что возвращает recv.
Но главное - ты неудасужился даже проверить что вернул connect
Потому как может ты даже не подключился, а пытаешься считать уже данные.
Также тебе нужны таймауты на connect

В моей статейке по винсоку (https://forum.antichat.ru/showpost.php?p=1331069&postcount=1) может почитать про таймаут на коннект.