Работа с сокетами
Работаю с сокетами, надо получить страничку сайта любого пока что. ну проблема заключается в том что отсылать данные у меня получается а принять ну ни как нихрена.. верней я их часть принимаю , да еще с какимто хвотом
вот код приемки
char szBuff[250];
int nSendSize = 250;//размер данных
int iCurrPoss = 0;
char book[10000];
int n = 100;
while(nSendSize>0)
{
int ret = recv(sClient, &szBuff[iCurrPoss], nSendSize, 0);
if (ret ==0)
break;
else if (ret == SOCKET_ERROR)
{
m_edit.SetWindowTextA("Error pri polychenii");
break;
}
nSendSize -= ret;
iCurrPoss +=ret;
strcpy(book,szBuff);
}
сдесь переменную book вывожу на экран
вот что мне он выводит :
HTTP/1.1 200 OK
Date: Mon, 28 Feb 2011 07:55:02 GMT
Server: Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny9 with Suhosin-Patch
X-Powered-By: PHP/5.2.6-1+lenny9
Vary: Accept-Encoding
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-EncodÌÌÌÌÌÌÌÌÌÌget
то есть он не до конца выводит
да еще и добовляет -> ÌÌÌÌÌÌÌÌÌÌget
я не понимаю от куда она
"\r\n"
"User-Agent: Mozilla/5.0\r\n"
"Accept: text/html\r\n"
"Accept-Language: ru,en-us;q=0.7,en;q=0.3\r\n"
"Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7\r\n"
"Connection: keep-alive\r\n\r\n";
вот этот .. но запрос тут не причем сервер же отвечает ..
моя прога их принять не может все посылаю запрос на
codenet.ru верней на его ip 46.4.77.42
Date: Mon, 28 Feb 2011 09:07:24 GMT
Server: Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny9 with Suhosin-Patch
X-Powered-By: PHP/5.2.6-1+lenny9
Vary: Accept-Encoding
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html
202b
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
<html><head>
<style type="text/css">
body {background-color: #ffffff; color: #000000;}
body, td, th, h1, h2 {font-family: sans-serif;}
pre {margin: 0px; font-family: monospace;}
a:link {color: #000099; text-decoration: none; background-color: #ffffff;}
a:hover {text-decoration: underline;}
table {border-collapse: collapse;}
.center {text-align: center;}
_________ну_и_так_далее_____________
покажи больше кода
char szBuffer[1024];
int ret, i;
struct sockaddr_in server;
struct hostent *host = NULL;
char szServerName[1024], szMessage[1024];
char m[] = "GET / HTTP/1.1\r\nHost: "
"\r\n"
"User-Agent: Mozilla/5.0\r\n"
"Accept: text/html\r\n"
"Accept-Language: ru,en-us;q=0.7,en;q=0.3\r\n"
"Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7\r\n"
"Connection: keep-alive\r\n\r\n";
char n[] = "get";
strcpy(szMessage, m);
strcpy(szServerName, "46.4.77.42");
sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sClient == INVALID_SOCKET)
{
m_edit.SetWindowTextA("Can't create socket");
exit;
}
else
{
m_edit.SetWindowTextA(m);
server.sin_family = AF_INET;
server.sin_port = htons(80);
server.sin_addr.s_addr = inet_addr(szServerName);
if (server.sin_addr.s_addr == INADDR_NONE)
{
host = gethostbyname(szServerName);
if (host == NULL)
{
m_edit.SetWindowTextA( "Unable to resolve server");
}
else
{
CopyMemory(&server.sin_addr, host->h_addr_list[0],
host->h_length);
}
}
else
{
if (connect(sClient, (struct sockaddr *)&server,
sizeof(server)) == SOCKET_ERROR)
{
m_edit.SetWindowTextA( "connect failed");
}
// Send and receive data
ret = send(sClient, szMessage, strlen(szMessage), 0);
if (ret == SOCKET_ERROR)
{
m_edit.SetWindowTextA("send failed");
}
else
{
char szBuff[250];
int nSendSize = 250;//размер данных
int iCurrPoss = 0;
char book[10000];
int n = 100;
while(nSendSize>0)
{
int ret = recv(sClient, &szBuff[iCurrPoss], nSendSize, 0);
if (ret ==0)
break;
else if (ret == SOCKET_ERROR)
{
m_edit.SetWindowTextA("Error pri polychenii");
break;
}
nSendSize -= ret;
iCurrPoss +=ret;
strcpy(book,szBuff);
}
m_edit2.SetWindowTextA(book);
closesocket(sClient);
}
}
}
да и m_echo и m_echo2 это текстовые поля куда выводится
в первой итерации в ret ты получаешь 250
в следующей итерации у тебя уже:
int ret = recv(sClient, &szBuff[250], 0, 0);
только благодаря нулю в 3 параметре, код не вылетает с ошибкой... далее так как nSendSize =0, recv ничего не принимает и цепочка -> ret = 0 -> break -> nSendSize = 0 -> оканчиваем цикл...
Поясняю функция recv во 2м параметре получает указатель на буфер, в 3м длину этого буфера, а возвращает количество принятых байт или 0 если прием окончен, ну и SOCKET_ERROR если ошибка
Соответственно своим алгоритмом ты получаешь первые 250 байт. Думай...
ща буду исправлять.
{
ret = recv(sClient, &szBuff[iCurrPoss], 1, 0);
if (ret==0)
{
break;
}
else if (ret == SOCKET_ERROR)
{
m_edit.SetWindowTextA("Error pri polychenii");
break;
}
iCurrPoss +=ret;
strcpy(book,szBuff);
}
m_edit2.SetWindowTextA(book);
а вот ошибка
Run-Time Check Failure #2 - Stack around the variable 'szBuff' was corrupted.
Из за чего может быть???
Ты вообще не понял про что я написал:)) и что-то судя по (&szBuff[iCurrPos]) у тебя пробелы в базовых знаниях языка
p.s. когда твой iCurrPos становится больше 250, ты выходишь за границы блока памяти который выделил. Отсюда ошибка
Пункт 3.3 посмотреть, скопировать, разобраться и будет работать
в функции recv нам нужно пока два параметра
2й - это указатель на блок памяти предварительно выделенный нами
3й - размер этого блока
функция возвращает целочисленное значение у тебя ret
ret > 0, успешно принято ret байт
ret == 0 , не принято (удаленный хост ничего не передает)
ret == SOCKET_ERROR, ошибка
ты работаешь с двумя буфферами хорошо...
Пускай первый будет большой char book[10000] - будем считать что он достаточно большой чтобы принять весь файл
и второй временный char szBuf[250];
int iCurPos = 0; - это вспомогательный указатель позиции(курсор)
теперь начинаем принимать
// итак принимаем данные
ret = recv(sClient,
&szBuf[0], // указываем на начало!!
sizeof(szBuf), // размер
0);
// обрабатываем ret
// если ret > 0 значит мы приняли какое-то количество байт переписываем их в наш основной буфер
if (ret > 0) {
memcpy(&book[iCurPos], // пишем в позицию iCurPos
&szBuf[0],
ret); // записываем только столько байт сколько получено
iCurPos += ret; // увеличиваем позицию
};
// если ret == SOCKET_ERROR обрабатываем ошибку
if (ret == SOCKET_ERROR) {
// Что-нибудь делаем
}
} while (ret != 0); // повторяем пока не закончится передача
&szBuf[0] - вот что это, это вы указываете на первый элемент в массиве как на обычную переменную , без инкрементации потому что это статический массив а не указатель. Хорошо что стке tcp - буферизирует вот и ошибки времени исполнения не видите, пример:
char book[10000];
char* fill = book;
int pos = 0;
char szBuff[250];
while(1) {
memset(szBuff, '\0', sizeof(szBuff));
ret = recv(sClient, szBuf, sizeof(szBuf), 0);
if(ret == SOCKET_ERROR || ! ret)
break;
if(sizeof(book) < pos + ret) {
send_error("Переполнение буфера, это просто пример, убери эту функцию");
break;
}
strncpy(fill + pos, szBuf, ret);
pos += ret;
}
// Здесь можешь предварить скаченное хозяйство нулём так как функция strncpy - нуль не копирует
book[ strlen(book) - 1 ] = '\0';
Типа этого попробуй, потестить.