информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Портрет посетителяВсе любят медСтрашный баг в Windows
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Бэкдор в xz/liblzma, предназначенный... 
 Три миллиона электронных замков... 
 Doom на газонокосилках 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
[C++] Как принять через сокет большой объём данных? 18.06.01 21:24  Число просмотров: 908
Автор: Delimiter Статус: Незарегистрированный пользователь
Отредактировано 18.06.01 21:31  Количество правок: 1
<"чистая" ссылка>
> Показываю
>
> char buf[0x300], buf2[0x5000];
я бы не советовал тебе так делать
используй
char *buf,*buf2;
.....................
buf=new char[0x300];
buf2=new char[0x5000];

> int n = 0;
> SOCKET s;
> LPHOSTENT lpHostEntry;
> SOCKADDR_IN saServer;
> lpHostEntry = gethostbyname("wwwserver");
> if(lpHostEntry == NULL)
> {
> return 0;
> }
> s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
> if(s == INVALID_SOCKET)
> {
> return 0;
> }
> saServer.sin_family = AF_INET;
> saServer.sin_addr =
> *((LPIN_ADDR)*lpHostEntry->h_addr_list);
> saServer.sin_port = htons(80);
... а где же bind
что должен испоkьзовать сокет со своей стороны или по умолчанию .....:)

> n = connect(s, (LPSOCKADDR)&saServer,
> sizeof(SOCKADDR_IN));
> if(n == SOCKET_ERROR)
> {
> return 0;
> }
> sprintf(buf, "GET / HTTP/1.1\r\nHost:
> wwwserver\r\nUser-Agent: Mozillo/5.0\r\n\r\n");
> UINT a = 0;
> UINT b = 0;
> b = 0;
> while(b < strlen(buf))
> {
> a = send(s, (char *)(buf + b), strlen(buf)
> - b, NULL);
а посылать мона и не побайтно
> b += a;
> }
> n = recv(s, buf2, sizeof(buf2), NULL);
>
> Вот и здесь в buf2 не вся инфа что должна


ты и не можешь получить все (или ты контролируешь сервак :)))
но я не думаю что его стек протоколов....
представь я сервер и я решил послать тебе пакет в три приема....:)
посмотри свой код ......ты получишь только первый :))))

возьми снифер и увидишь что именно происходит

сам исправишь или ГДЕ?

ну и в конце
delete[] buf;
delete[] buf2;
<programming>
[C++] Как принять через сокет большой объём данных? 18.06.01 16:57  
Автор: myrmidon Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Как принять большой объём данных, около 50-60 килобайт?
пробывал как обычно - char buf[0x5000];
recv(s, buf, sizeof(buf), 0);
Принимается, но только первые 1-2 килобайта, и всё!
Пробывал даже через CSocket, таже муйня, чо делать??
[C++] Как принять через сокет большой объём данных? 18.06.01 17:32  
Автор: Delimiter Статус: Незарегистрированный пользователь
Отредактировано 19.06.01 05:49  Количество правок: 1
<"чистая" ссылка>
> Как принять большой объём данных, около 50-60 килобайт?
> пробывал как обычно - char buf[0x5000];
> recv(s, buf, sizeof(buf), 0);
> Принимается, но только первые 1-2 килобайта, и всё!
> Пробывал даже через CSocket, таже муйня, чо делать??

я че то не понял char buf[0x5000]; -это ты так объявляешь?
смотри на мое обьявление inquire
но не забудь сделать
delete[] buf;

через этот кусок я пропускал и по 1-му мегобайту

ioctlsocket(clientr1h,FIONREAD,&arg);
....
...
char *inquire=new char[arg+2];
for(int i=0;i<arg+2;i++)
*(inquire+i)=0;
int len=recv(clientr1h,inquire,arg,0);
.....
.....
int mlen=send(clientr2,inquire,arg,0);
delete[] inquire;
[C++] Как принять через сокет большой объём данных? 18.06.01 19:14  
Автор: myrmidon Статус: Незарегистрированный пользователь
<"чистая" ссылка>
А по побробнее плиз!
[C++] Как принять через сокет большой объём данных? 18.06.01 20:21  
Автор: Delimiter Статус: Незарегистрированный пользователь
<"чистая" ссылка>
> А по побробнее плиз!
поподробнее скажи че хочешь написать я те брошу source
или покажи свой здеся быстро вылечат.. :))
[C++] Как принять через сокет большой объём данных? 18.06.01 20:49  
Автор: myrmidon Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Показываю

char buf[0x300], buf2[0x5000];
int n = 0;
SOCKET s;
LPHOSTENT lpHostEntry;
SOCKADDR_IN saServer;
lpHostEntry = gethostbyname("wwwserver");
if(lpHostEntry == NULL)
{
return 0;
}
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(s == INVALID_SOCKET)
{
return 0;
}
saServer.sin_family = AF_INET;
saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
saServer.sin_port = htons(80);
n = connect(s, (LPSOCKADDR)&saServer, sizeof(SOCKADDR_IN));
if(n == SOCKET_ERROR)
{
return 0;
}
sprintf(buf, "GET / HTTP/1.1\r\nHost: wwwserver\r\nUser-Agent: Mozillo/5.0\r\n\r\n");
UINT a = 0;
UINT b = 0;
b = 0;
while(b < strlen(buf))
{
a = send(s, (char *)(buf + b), strlen(buf) - b, NULL);
b += a;
}
n = recv(s, buf2, sizeof(buf2), NULL);

Вот и здесь в buf2 не вся инфа что должна
[C++] Как принять через сокет большой объём данных? 18.06.01 21:24  
Автор: Delimiter Статус: Незарегистрированный пользователь
Отредактировано 18.06.01 21:31  Количество правок: 1
<"чистая" ссылка>
> Показываю
>
> char buf[0x300], buf2[0x5000];
я бы не советовал тебе так делать
используй
char *buf,*buf2;
.....................
buf=new char[0x300];
buf2=new char[0x5000];

> int n = 0;
> SOCKET s;
> LPHOSTENT lpHostEntry;
> SOCKADDR_IN saServer;
> lpHostEntry = gethostbyname("wwwserver");
> if(lpHostEntry == NULL)
> {
> return 0;
> }
> s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
> if(s == INVALID_SOCKET)
> {
> return 0;
> }
> saServer.sin_family = AF_INET;
> saServer.sin_addr =
> *((LPIN_ADDR)*lpHostEntry->h_addr_list);
> saServer.sin_port = htons(80);
... а где же bind
что должен испоkьзовать сокет со своей стороны или по умолчанию .....:)

> n = connect(s, (LPSOCKADDR)&saServer,
> sizeof(SOCKADDR_IN));
> if(n == SOCKET_ERROR)
> {
> return 0;
> }
> sprintf(buf, "GET / HTTP/1.1\r\nHost:
> wwwserver\r\nUser-Agent: Mozillo/5.0\r\n\r\n");
> UINT a = 0;
> UINT b = 0;
> b = 0;
> while(b < strlen(buf))
> {
> a = send(s, (char *)(buf + b), strlen(buf)
> - b, NULL);
а посылать мона и не побайтно
> b += a;
> }
> n = recv(s, buf2, sizeof(buf2), NULL);
>
> Вот и здесь в buf2 не вся инфа что должна


ты и не можешь получить все (или ты контролируешь сервак :)))
но я не думаю что его стек протоколов....
представь я сервер и я решил послать тебе пакет в три приема....:)
посмотри свой код ......ты получишь только первый :))))

возьми снифер и увидишь что именно происходит

сам исправишь или ГДЕ?

ну и в конце
delete[] buf;
delete[] buf2;
[C++] Как принять через сокет большой объём данных? 19.06.01 01:52  
Автор: kabanchik Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Delimiter, этот парень смышленный, ему просто надо технику показать, дальше он сам пойдет. а ща он наврят ли поймет что и почему не правильно сделал. не мучай его :)))


> > Показываю
> >
> > char buf[0x300], buf2[0x5000];
> я бы не советовал тебе так делать
> используй
> char *buf,*buf2;
> .....................
> buf=new char[0x300];
> buf2=new char[0x5000];
>
> > int n = 0;
> > SOCKET s;
> > LPHOSTENT lpHostEntry;
> > SOCKADDR_IN saServer;
> > lpHostEntry = gethostbyname("wwwserver");
> > if(lpHostEntry == NULL)
> > {
> > return 0;
> > }
> > s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
> > if(s == INVALID_SOCKET)
> > {
> > return 0;
> > }
> > saServer.sin_family = AF_INET;
> > saServer.sin_addr =
> > *((LPIN_ADDR)*lpHostEntry->h_addr_list);
> > saServer.sin_port = htons(80);
> ... а где же bind
> что должен испоkьзовать сокет со своей стороны или по
> умолчанию .....:)
>
> > n = connect(s, (LPSOCKADDR)&saServer,
> > sizeof(SOCKADDR_IN));
> > if(n == SOCKET_ERROR)
> > {
> > return 0;
> > }
> > sprintf(buf, "GET / HTTP/1.1\r\nHost:
> > wwwserver\r\nUser-Agent: Mozillo/5.0\r\n\r\n");
> > UINT a = 0;
> > UINT b = 0;
> > b = 0;
> > while(b < strlen(buf))
> > {
> > a = send(s, (char *)(buf + b), strlen(buf)
> > - b, NULL);
> а посылать мона и не побайтно
> > b += a;
> > }
^^^^^^^^^^^^^^^^^^^^
тут вызывай сразу
send(s, buf, strlen(buf) + 1);
Delimiter прав, нет смысла посылать по байтово.
ты изначально создал сокет - Blocking, т.е. любая операция у тебя останавливает поток, пока не закончишь действие. т.е. тут пока твои данные не отправятся (вызывая send) ты не сможешь продолжить программу. так что будь спокоен.

> > n = recv(s, buf2, sizeof(buf2), NULL);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
а вот ту делай цикл, если тебе удобно или хочется все в один буфер, то делай так
char* data = buf2;
int nSize = 0x5000;
a = b =0;
while (nSize >0 && (a = recv(s, data, nSize)) != SOCKET_ERROR)
{
if (a == 0)
break;
data += a;
nSize -= (int)a;
}
сюда попадаем либо если все данные получили, либо буффер забит, либо ошибка при получении.
а цикл делаешь т.к. сервер сразу не пошлет тебе все данные. а если и пошлет, все равно ты их сразу не получишь, а получать будешь частично.

тут конечно :
closesocket(s);
delete [] buf1;
delete [] buf2;
если выделял как Delimiter говорил, а он правильно говорил, большую память лучше выделять динамически.
:)) или... 19.06.01 04:29  
Автор: Delimiter Статус: Незарегистрированный пользователь
Отредактировано 19.06.01 05:45  Количество правок: 5
<"чистая" ссылка>
Все что написал Kabanchik правильно ....я всегда за помощью к
нему обращаюсь.... и тебе советую :))

дальнейшее просто для твоих размышлений :))
Так как вижу ты HTTPить решил :))
можно конечно и FTP и Gopher прописать на Винсоке :))
но...

делаишь простенький диалог с 2-мя СEditBox первую простую
вторую как multyline побольше
с первой свяжи CString m_str1, со второй CString m_str2
ну и кнопку для запуска всего этого хозяйства :))


тогда твой запрос

void ImiaDialoga::MyReqest()
{
UpdateData(true);
CInternetSession session;
m_str2=CString("Let's go\r\n");
CInternetFile* file=NULL;
try
{
file=(CInternetFile *) session.OpenURL(m_str2);
}
catch(CInternetException* pEx)
{
file=NULL;
pEx->Delete();
}
if(file)
{
m_str2+=CString("First rezult :))\r\n");
CString line;
for(;file->ReadString(line);)
{
m_str2+=line+"\r\n";
UpdateData(false);
}
file->Close();
delete file;
}
else
{
m_str2+=CString("Dik netu tuta nichego!");
}
m_str2+=CString("Jirnii konec===========================");
}


p.s. Да чуть не забыл
подключи #include "afxinet.h"


а в винсоке же старайся пользовать сразу WSA
.....без тормозов :))
почитай про события и как их ловить... и
можешь начинать читать про WSAAsyncSelect() :))

другайя альтернатива создай слушающий сокет как thread
но для общения опять лучше исполтзовать события я
обычно сливаю в volatile и шлю сообщение основной задаче
чтоб она обновила свои боксы и листы ......и чтобы узнать об
окончании thread


зато будешь удовольствие получать от своих прог :))
:)) или... 19.06.01 06:06  
Автор: Delimiter Статус: Незарегистрированный пользователь
Отредактировано 19.06.01 06:07  Количество правок: 1
<"чистая" ссылка>
а от тормозных геморой :))
:)) или... 19.06.01 10:35  
Автор: myrmidon Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Вообще я делаю в отдельном потоке, поэтому посрать на блокирующие сокеты
А сам я сделал так :
char buf2[0x900];
int n = 0;
while(n = recv(s, buf2, sizeof(buf2), 0))
{
if(n == SOCKET_ERROR)
{
return 0;
}
}
:)) или... 19.06.01 11:33  
Автор: Delimiter Статус: Незарегистрированный пользователь
Отредактировано 19.06.01 12:09  Количество правок: 1
<"чистая" ссылка>
> Вообще я делаю в отдельном потоке, поэтому посрать на
> блокирующие сокеты
> А сам я сделал так :
> char buf2[0x900];
> int n = 0;
> while(n = recv(s, buf2, sizeof(buf2), 0))
> {
> if(n == SOCKET_ERROR)
> {
> return 0;
> }
> }
do {
ioctlsocket(s,FIONREAD,&arg);
char *buf=new char[arg+2];
n=recv(s,buf,arg,0);
*(buf+arg+1)=0; // только изза любви к strcat :))

strcat(charstr,buf); /// выкидываем в volatile buffer или ты будешь
// затирать предыдущий :))

//а здесь я бы послал сообщение основной задаче
// ....ну чтоб результат на ЛИЦО (типа в рожу :)
::PostMessage((HWND)param,WM_PORAUPDATE,0,0);
delete[] buf;
} while( n! = SOCKET_ERROR|n!=0);


не забудь
const WM_PORAUPDATE=WM_USER+100;

если проблема написать обработчик WM_PORAUPDATE
пиши помогем у мя знаний мало но теми что есь поделюсь:))
[C++] вот так 18.06.01 17:22  
Автор: XR <eXtremal Research> Статус: The Elderman
Отредактировано 18.06.01 17:27  Количество правок: 1
<"чистая" ссылка>
> Как принять большой объём данных, около 50-60 килобайт?
> пробывал как обычно - char buf[0x5000];
> recv(s, buf, sizeof(buf), 0);
> Принимается, но только первые 1-2 килобайта, и всё!
> Пробывал даже через CSocket, таже муйня, чо делать??
      off = 0;
      while(nByte!=0) 
                 {
		  nByte = recv(cs,buf+off,sizeof(buf)-off,0);
                  off  +=nByte;
		 }

---

проверки опущены ....
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 1 s   Design: Vadim Derkach