как прочитать все ответы сервера из сокета? - PullRequest
1 голос
/ 19 марта 2009

У меня очень большая проблема ... Я работаю с сокетами в C. Я отправляю запрос на сервер, который отправляет мне много ответов. Проблема в том, что клиент получает первый ответ, а затем соединение закрывается. Что я могу сделать? Я пытался с setsockopt() ... SO_KEEPALIVE или SO_LINGER, но я не решил проблему. Вы можете мне помочь? Большое спасибо


Чтобы быть более понятным, вот код. Сокет автоматически закрывается через определенное время или после того, как клиент получил первый ответ ... Я не уверен.

char* demarre_client( client_args * c_args,char* message, /*char* SERVEUR_PORT*/int port){
int socket_client=socket(PF_INET,SOCK_STREAM,0);
memset(&(c_args->adresse_serveur),0,sizeof(c_args->adresse_serveur));
c_args->adresse_serveur.sin_family=AF_INET;
c_args->adresse_serveur.sin_addr.s_addr=inet_addr(SERVEUR_IP);
//int port=APHash(SERVEUR_PORT,strlen(SERVEUR_PORT));
c_args->adresse_serveur.sin_port=htons(port);
int err=0;

if ((err=connect(socket_client, (struct sockaddr *) &(c_args->adresse_serveur), sizeof(c_args->adresse_serveur)))<0)
{
    printf("CONNECT error %d\n", errno);
    exit(-1);
}
if (send(socket_client, message, strlen(message), 0)!=strlen(message))
{
    printf("send error!!\n");
    exit(-2);
}
char* raspFin=(char* )malloc(sizeof(char)*1024);
strcpy(raspFin,"");
int num=-1;
int nn=0;
char* rasp=(char* )malloc(sizeof(char)*1024);
memset (rasp, 0, 1024 * sizeof(char ));
    /* here it reads the first response and after he get out of while */
while ((num=recv(socket_client, rasp,1024,MSG_WAITALL))>0)
{
    printf("recu %s mun=%d\n" , rasp,num);
    strcat(raspFin,rasp);
    strcat(raspFin,"\n");
    rasp=(char* )malloc(sizeof(char)*1024);
    memset (rasp, 0, 1024 * sizeof(char ));

}

if (num<0)
{
    printf("rasp error!!\n");
    exit(-3);
}

Ответы [ 2 ]

4 голосов
/ 19 марта 2009

Вы уверены, что не получите все ответы при первом звонке?

TCP / IP является потоковым протоколом без встроенного управления потоком, поэтому различные сообщения, отправленные с использованием отдельных вызовов send(), могут быть получены за один recv(). Поскольку вы используете printf(), он печатает буфер, пока не увидит нулевой терминатор - может быть, другие ответы помимо терминатора?

Попробуйте использовать какой-либо элемент управления потоком, такой как отправка префикса длины сообщения или использование некоторых специальных символов (например, STX / ETX, но убедитесь, что ваше сообщение не содержит таких символов). Если вы планируете использовать это программное обеспечение, вам все равно придется реализовать управление потоком.

А пока попробуйте заменить printf() на

char *ptr;
for (ptr = buffer; ptr <= buffer + num; ptr += strlen(ptr)+1;)
    printf("%s\n", ptr);

Он напечатает все строки из вашего буфера ответов.

И вам не нужно malloc() внутри цикла - вы теряете память.

BTW SO_KEEPALIVE и SO_LINGER не имеют никакого отношения к этой проблеме.

2 голосов
/ 19 марта 2009

Я бы предложил запустить Анализатор сети Wireshark и посмотреть, что происходит в пакетном режиме. В наборе фильтров

tcp.srcport == <insert_server_port> || tcp.dstport == <insert_server_port>

Вы должны увидеть, на какие данные отправляются данные и кто закрывает соединение (отправляет пакеты FIN / RST).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...