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


Автор: fire64 13.10.2008, 14:33
Здравствуйте, я написал программу работающую с UDP пакетами, но столкнулся с серьёзной проблемой.
дело в том что пакеты в консоли обрезаются

вывод в консоли обрезается если в пакете встречается 00 в хексе виде

Код

#include<stdio.h>
#include<string.h>
#include<winsock2.h>
#include<windows.h>


#define PORT  27015
#define SERVERADDR  "78.107.233.235"
#define MSG "\xFF\xFF\xFF\xFF\x55\x0E\x5C\x32\x1E"


int main ( int argc, char*  argv [ ] )
{

    
            WSADATA wsaData;
            int  BufLen = 10024;
            char RecvBuf[10024];


              if (WSAStartup(MAKEWORD(2,2), &wsaData))
              {
                                      printf  (" WSAStartup     error:   %d\n ", WSAGetLastError ( ) );
                                      return  -1;
               }


               SOCKET  name_sock=socket ( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
               if   ( name_sock==INVALID_SOCKET )
               {
                                      printf (" socket ( ) error: %d \n ", WSAGetLastError ( ) );
                                      WSACleanup ( );
                                      return -1;
               }

              HOSTENT  *hst;
              sockaddr_in  dest_addr;

              dest_addr.sin_family=AF_INET;
              dest_addr.sin_port=htons ( PORT );

               if    (inet_addr ( SERVERADDR )) dest_addr.sin_addr.s_addr=inet_addr ( SERVERADDR );
              else
                         if   ( hst=gethostbyname ( SERVERADDR )) dest_addr.sin_addr.s_addr=((unsigned long  **)
                                                                                                                                hst->h_addr_list)[0][0];
              else
                         {
                                       printf ("Unknown host:  %d \n", WSAGetLastError ( ));
                                       closesocket ( name_sock );
                                       WSACleanup ( );
                                       return -1;
                          }


                            int poket= sizeof ( MSG )-1;


                           sendto(name_sock, MSG, poket, 0,(sockaddr  *)  &dest_addr, sizeof(dest_addr));

                           sockaddr_in   server_addr;
                           int server_addr_size=sizeof (server_addr);

                           int  n=recvfrom (name_sock, RecvBuf, sizeof(RecvBuf),0,(sockaddr  *) &server_addr, &server_addr_size);

                           if  ( n==SOCKET_ERROR)
                           {
                                        printf ("recvfrom ( ) error:  %d\n", WSAGetLastError ( ) );
                                        closesocket(name_sock);
                                        WSACleanup ( );
                                        return -1;
                           }

   

strcat(RecvBuf, "\0");

                           
//while(n > 0)
   printf("%s\n", RecvBuf);


                closesocket (name_sock);
                WSACleanup ( );
                 return  0;
}  


Автор: ptr 13.10.2008, 15:14
Замени
Код
strcat(RecvBuf, "\0");

на 
Код
RecvBuf[n]='\0';


И кстати '\0' вместо "\0".

Автор: fire64 13.10.2008, 15:26
это конечно хорошо, но всёравно выводится только первая строка пакета

Автор: ptr 13.10.2008, 15:37
А ты уверен что у тебя в буфере весь пакет?

Автор: fire64 13.10.2008, 15:41
 recvfrom (name_sock, RecvBuf, sizeof(RecvBuf),0,(sockaddr  *) &server_addr, &server_addr_size);

а разве функция recvfrom  заносит не весь пакет в буфер ?

объем буфера у меня конечно больше чем размер пакета

Автор: ptr 13.10.2008, 15:49
Цитата

recvfrom возвращает уже доступные данные вплоть до запрошенного объема, и не ждет, пока появятся данные полной запрошенной длины

Она вообще ничего про твои пакеты не знает.

Автор: fire64 13.10.2008, 15:54
ptr, не подскажешь как получить полный пакет ?

Автор: ptr 13.10.2008, 16:07
Размер пакета ты знаешь, количество принятых байт знаешь. Просто собирай пакеты из принятых буферов.

Автор: Олег2005 18.10.2008, 20:17
Блокирующий recvfrom () возвращает управление в программу только после того, как в сокет прийдет вся UDP-датаграмма.
Стивенс утверждает, что обрезка истинно происходит только в том случае, если буфер recvfrom меньше пришедшей датаграммы. 
Если выдать recvmsg() на такой датаграмме, то она вернет флаг MSG_TRUNC  в соответствующем поле структуры msghdr - но это на некоторых *nix системах. 

Автор: J0ker 20.10.2008, 01:10
UDP пакеты не сегментируются и приходят целиком (или не приходят вообще  smile )
также они не объединяются
recvfrom извлекает очередную датаграмму и обрезает ее если она больше буфера - остаток теряется.

Автор: Олег2005 20.10.2008, 12:47
Цитата(J0ker @  20.10.2008,  00:10 Найти цитируемый пост)
UDP пакеты не сегментируются и приходят целиком (или не приходят вообще  smile )

О чем и речь!

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