Все что написал Kabanchik правильно ....я всегда за помощью к
нему обращаюсь.... и тебе советую :))
дальнейшее просто для твоих размышлений :))
Так как вижу ты HTTPить решил :))
можно конечно и FTP и Gopher прописать на Винсоке :))
но...
делаишь простенький диалог с 2-мя СEditBox первую простую
вторую как multyline побольше
с первой свяжи CString m_str1, со второй CString m_str2
ну и кнопку для запуска всего этого хозяйства :))
p.s. Да чуть не забыл
подключи #include "afxinet.h"
а в винсоке же старайся пользовать сразу WSA
.....без тормозов :))
почитай про события и как их ловить... и
можешь начинать читать про WSAAsyncSelect() :))
другайя альтернатива создай слушающий сокет как thread
но для общения опять лучше исполтзовать события я
обычно сливаю в volatile и шлю сообщение основной задаче
чтоб она обновила свои боксы и листы ......и чтобы узнать об
окончании thread
зато будешь удовольствие получать от своих прог :))
Как принять большой объём данных, около 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 Статус: Незарегистрированный пользователь
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 говорил, а он правильно говорил, большую память лучше выделять динамически.
Все что написал Kabanchik правильно ....я всегда за помощью к
нему обращаюсь.... и тебе советую :))
дальнейшее просто для твоих размышлений :))
Так как вижу ты HTTPить решил :))
можно конечно и FTP и Gopher прописать на Винсоке :))
но...
делаишь простенький диалог с 2-мя СEditBox первую простую
вторую как multyline побольше
с первой свяжи CString m_str1, со второй CString m_str2
ну и кнопку для запуска всего этого хозяйства :))
p.s. Да чуть не забыл
подключи #include "afxinet.h"
а в винсоке же старайся пользовать сразу WSA
.....без тормозов :))
почитай про события и как их ловить... и
можешь начинать читать про WSAAsyncSelect() :))
другайя альтернатива создай слушающий сокет как thread
но для общения опять лучше исполтзовать события я
обычно сливаю в volatile и шлю сообщение основной задаче
чтоб она обновила свои боксы и листы ......и чтобы узнать об
окончании thread
зато будешь удовольствие получать от своих прог :))
Вообще я делаю в отдельном потоке, поэтому посрать на блокирующие сокеты
А сам я сделал так :
char buf2[0x900];
int n = 0;
while(n = recv(s, buf2, sizeof(buf2), 0))
{
if(n == SOCKET_ERROR)
{
return 0;
}
}
> Вообще я делаю в отдельном потоке, поэтому посрать на > блокирующие сокеты > А сам я сделал так : > 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;
}