Форум: Форум C++Разное
Новые темы: 00
PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум C++

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Принятие данных (recv) - сокеты
 
 автор: Trunk   (29.01.2007 в 11:11)   письмо автору
 
 


char buff[20*1024];
while( bytes_recv = recv(my_sock,(char*) &buff,sizeof(buff),0))
{
   ////
}

Проблема в том, что принятые данные не накапливаются в буфере, а перезаписываются в первой позиции буфера. В чём может быть проблема? Проверяю через telnet.

  Ответить  
 
 автор: cheops   (29.01.2007 в 13:15)   письмо автору
 
   для: Trunk   (29.01.2007 в 11:11)
 

Всё правильно, буфер не накапливает данные - он их извлекает, вам потребуется самому их складывать в отдельную переменную, например result
char buff[20*1024]; // А тут можно поменьше
char result[20*1024]; // Здесь нужно выделить памяти побольше
while( bytes_recv = recv(my_sock,(char*) &buff,sizeof(buff),0))
{
   strcat(result, buff);
}

  Ответить  
 
 автор: TrunK   (29.01.2007 в 13:53)   письмо автору
 
   для: cheops   (29.01.2007 в 13:15)
 

Странно, написал как Вы сказали, и после отправки символа (первого) прграмма завершает работу... Причём никаких ошибок отследить не удалось

  Ответить  
 
 автор: cheops   (29.01.2007 в 16:02)   письмо автору
 
   для: cheops   (29.01.2007 в 13:15)
 

У вас имеется возможность использовать STL?

  Ответить  
 
 автор: TrunK   (29.01.2007 в 16:47)   письмо автору
 
   для: cheops   (29.01.2007 в 16:02)
 

Ну судя по всему такая возможность есть.
Только не могу поять чем мне это поможет...

  Ответить  
 
 автор: cheops   (29.01.2007 в 17:26)   письмо автору
 
   для: TrunK   (29.01.2007 в 16:47)
 

В этом случае можно использовать строку string, которая автоматически расширяется и складывать данные туда - этот класс автоматически следит за памятью... хотя и представленный выше вариант тоже должен работать без вопросов... памяти выделено достаточно? Вы большой объём ожидаете через сокет?

  Ответить  
 
 автор: Trunk   (29.01.2007 в 19:02)   письмо автору
 
   для: cheops   (29.01.2007 в 17:26)
 

Насчёт предыдущего варианта:
Как можно проверить достаточность выделения памяти?
Пока я собираюсь получить хотя бы байт =)

  Ответить  
 
 автор: cheops   (29.01.2007 в 19:12)   письмо автору
 
   для: Trunk   (29.01.2007 в 19:02)
 

Сделайте пока поменьше размер buff - на таком объёме под PHP сокеты захлёбываются 100%, если вы тащите данные из Интернет... размер строки будет обпределяться тем, сколько данных примете - именно поэтому лучше использовать string, который сам расширяется по мере надобности. Если будете использовать обычные C-строки и выйдете за границу массива - перепашете соседнюю область программы и она скорее всего просто аварийно завершится.

  Ответить  
 
 автор: Trunk   (29.01.2007 в 19:54)   письмо автору
 
   для: cheops   (29.01.2007 в 19:12)
 

Как это сделать используя string?
Это функции из STL библиотеки?

  Ответить  
 
 автор: cheops   (29.01.2007 в 20:15)   письмо автору
 
   для: Trunk   (29.01.2007 в 19:54)
 

Вот небольшой пример
#include <string>
#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
    char buff[20*1024];
    string str = "";

    buff[0] = '1';
    buff[1] = '\0';
    str.append(buff);
    buff[0] = '2';
    buff[1] = '\0';
    str.append(buff);

    cout << str << endl;
    
    return 0;
}

Т.е. ваш блок может выглядеть так
char buff[20*1024];
string str = "";
while( bytes_recv = recv(my_sock,(char*) &buff,sizeof(buff),0))
{
    str.append(buff);
}

  Ответить  
 
 автор: Trunk   (29.01.2007 в 20:31)   письмо автору
 
   для: cheops   (29.01.2007 в 20:15)
 


error C2679: binary '<<' : no operator defined which takes a right-hand operand of type 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' (or there is no acceptable conversion)
Error executing cl.exe.

Это на строчку:

cout << str << endl;

  Ответить  
 
 автор: cheops   (29.01.2007 в 21:29)   письмо автору
 
   для: Trunk   (29.01.2007 в 20:31)
 

Хм... а у вас какой компилятор используется?

  Ответить  
 
 автор: Trunk   (29.01.2007 в 22:20)   письмо автору
 
   для: cheops   (29.01.2007 в 21:29)
 

Пользуюсь Visual C++ 6.0
Ура! Работает!!!
Фух, одна проблема почти решена =)


while(bytes_recv = recv(my_sock,(char*) &buff,1,0))
{
////
}

В буфер попдает "мусор". Т.е. в нулевом смещении стоит полученный байт, а остальное место заполняется мусором... Может это просто проблема программы telnet ? Потому что, судя по опытам, она посылает "посимвольно"...

  Ответить  
 
 автор: cheops   (30.01.2007 в 00:02)   письмо автору
 
   для: Trunk   (29.01.2007 в 22:20)
 

А вы нулевой символ должны ставить самостоятельно (дело в том, что если он не установлен - строка отображает и то, что идёт за полезными данными, т.е. соседние области программы)... Вы с каким протоколом работаете?

  Ответить  
 
 автор: Trunk   (30.01.2007 в 17:13)   письмо автору
 
   для: cheops   (30.01.2007 в 00:02)
 


socket(AF_INET,SOCK_STREAM,0)

Мне вот непонятно... Т.е. recv(my_sock,(char*) &buff,1,0) будет принимать только 1 байт?
И после каждого приёма надо будет добавлять "/0" ?

  Ответить  
 
 автор: cheops   (30.01.2007 в 23:25)   письмо автору
 
   для: Trunk   (30.01.2007 в 17:13)
 

Да в общем нет, должен принимать до конца строки, вы по какому протоколу работаете?

  Ответить  
 
 автор: cheops   (29.01.2007 в 21:32)   письмо автору
 
   для: Trunk   (29.01.2007 в 20:31)
 

Если ему не нравится, попробуйте так вывести
cout << str.c_str() << endl;

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования