Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > Отправляю строку но доходит не вся


Автор: iPlay 7.2.2011, 00:12
Есть клиент который отправляет строку длиной в 1024 символа, но доходит почему-то стабильно 48  smile 
Код

  cout << map;
  //тут не могу правильно длину строки отправить но на стороне сервера подправил
  //char len = map.length(); 
  //send(S,&len,4,0);
  send(S,map.c_str(),map.length(),0);
  closesocket(S);


Что может быть не так?

Сервер:
Код

void main()
{
  WSAData WSData;
  WSAStartup(0x101,&WSData);
  SOCKET S = socket(AF_INET,SOCK_STREAM,0);
  sockaddr_in SA;
  SA.sin_family=AF_INET;
  SA.sin_port=htons(3135);
  SA.sin_addr.S_un.S_addr=INADDR_ANY;
  bind(S,(sockaddr*)&SA,sizeof(SA));
  listen(S,SOMAXCONN);
  
  SOCKET NS;
  while ((NS = accept(S,0,0))!=INVALID_SOCKET)
  {
    cout<<"-------------------->\n";
    cout<<"Connected...\n";
    
    char n = 0;
    recv(NS,&n,1,0);
    
    cout<<"Received Length = "<< int(n) <<"\n";
    char* a=new char[1024];
    
    recv(NS,a,n,0);
    cout<<"Received: \"";    
        for (int i=0;i<1023;i++) 
            { 
                cout<<a[i]; 
            }
    cout<<"\"\n";
    closesocket(NS);
    cout<<"-------------------->\n";
  }
  closesocket(S);
  int n;
}

Автор: cutwater 7.2.2011, 00:54
Цитата(iPlay @  6.2.2011,  23:12 Найти цитируемый пост)
 char n = 0;


Первое что бросается в глаза. Вы хотите прочесть 1024 символа. Размер передаваемых храните и получаете в переменную типа char, которая имеет размер 1 байт, и соответственно диапазон догадываетесь какой?

Автор: iPlay 7.2.2011, 12:58
Я модифицировал код сервера, теперь он принимает нормально всё сообщение:
Код

void main()  {
        WSAData WSData;
        WSAStartup(0x101,&WSData);
        SOCKET mysocket = socket(AF_INET,SOCK_STREAM,0);
        
        sockaddr_in socketaddr;
        socketaddr.sin_family = AF_INET;
        socketaddr.sin_port = htons(3135);
        socketaddr.sin_addr.S_un.S_addr =  INADDR_ANY;
 
        bind(mysocket,(sockaddr*)&socketaddr,sizeof(socketaddr)); 
               
        listen(mysocket,SOMAXCONN); 

        cout << "-------------------->\n";
        cout << "Waiting for the Client..." << endl;
 
        char buffer[2048];
        
            while ((mysocket = accept(mysocket,0,0)) != INVALID_SOCKET)
            {
                cout << "Client Connected" << endl;
                
                int ret = recv(mysocket, buffer, 2048, 0);    
                buffer[ret] = '\0';
                cout << "\nReceived message: " << buffer << endl;    
                cout << "--------------------->\n";
            }
        closesocket(mysocket);
        WSACleanup();
        system("Pause");
}

Только получил другую проблему сервер перестал постоянно слушать сообщения от клиента, не могу понять что не так, вроде логику не изменил...

Автор: iPlay 7.2.2011, 13:36
И еще если я хочу посмотреть время отправки данного блока информации, такой способ валидный?
Код

    QueryPerformanceCounter( &start );
    send(mysocket,map.c_str(),map.length(),0);
    QueryPerformanceCounter( &finish );
    
    double sendtime = (finish.QuadPart - start.QuadPart) / (double)freq.QuadPart;
    printf("\n%f", sendtime); printf(" seconds\n");


Автор: borisbn 7.2.2011, 15:53
Цитата(iPlay @  7.2.2011,  13:36 Найти цитируемый пост)
 такой способ валидный?


Из документации по send
Цитата
If no error occurs, this function returns the total number of bytes sent, which can be less than the number indicated by len for nonblocking sockets.


и

Цитата
The successful completion of a send call does not indicate that the data was successfully delivered.


Т.о. ф-ция send может вернуть управление моментально, а потом в фоне отправлять, и твои измерения будут не совсем (совсем не) корректные

P.S. Не советую называть переменные так же, как имяена stl-ных классов

Цитата(iPlay @  7.2.2011,  13:36 Найти цитируемый пост)
map.c_str(),map.length()


Автор: iPlay 7.2.2011, 18:27
А каким образом тогда можно измерит время передачи блока информации?

Автор: borisbn 7.2.2011, 18:40
оттуда же
Цитата

The select or WSAEventSelect function can be used to determine when it is possible to send more data.

Автор: iPlay 7.2.2011, 19:24
Почитал, чёто не могу понять как её прикрутить чтобы точно получить события начала и окончания передачи.

Автор: borisbn 7.2.2011, 21:31
насколько я понял
Код

QueryCounter 1
send( the_socket, ...
select( the_socket, ...
QueryCounter 2

но могу и ошибаться

Автор: Олег2005 8.2.2011, 13:39
Цитата(borisbn @  7.2.2011,  14:53 Найти цитируемый пост)
Т.о. ф-ция send может вернуть управление моментально, а потом в фоне отправлять,

Так может работаnь только send() на сокете, объявленном неблокирующем.
На обычном блокирующем сокете функция блокирует процесс до тех пор, пока не передаст весь свой буфер в модуль TCP.

Добавлено через 4 минуты и 42 секунды
Цитата(iPlay @  7.2.2011,  18:24 Найти цитируемый пост)
Почитал, чёто не могу понять как её прикрутить чтобы точно получить события начала и окончания передачи. 

Таких событий не существует.
Обычно время передачи (приема) от передатчика до приемника рассчитывается по опции TIMEStamp в заголовке TCP-фрагмента.
Если вы не формируете сами этот заголовок - то надо придумывать какие-то свои собственные способы - сделав свой таймер...... 

Автор: iPlay 8.2.2011, 13:45
То есть проверка тем способом что я указал валидна, я так понимаю?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)