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





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
[C++] Как принять через сокет большой объём данных? 18.06.01 19:14  Число просмотров: 893
Автор: myrmidon Статус: Незарегистрированный пользователь
<"чистая" ссылка>
А по побробнее плиз!
<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: 0 s   Design: Vadim Derkach