2014-01-19 2 views
0

У меня возникли проблемы с чтением более 15 байтов с recvfrom, я попытался изменить параметр SO_RCVBUF и увеличил размер аргумента recvfrom, но все еще только прочитал 15 байт.recvfrom только читать 15 байт

int a = 65535; 
if (setsockopt(sd, SOL_SOCKET, SO_RCVBUF, &a, sizeof(int)) == -1) { 
    fprintf(stderr, "Error setting socket opts: %s\n", strerror(errno)); 
} 
... 
bytes = recvfrom(sd, buffer, 2048, 0,(struct sockaddr *) &addr, &addr_len); 

но функция recvfrom по-прежнему считывает только 15 байт.

clientUDP.c

#include <sys/socket.h> 
#include <string.h> 
#include <arpa/inet.h> 
#include <stdio.h> 

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

    int sd, addr_len, bytes; 
    char buffer[2048]; 
    struct sockaddr_in addr; 
    sd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 
    bzero (&addr, sizeof (addr)); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(8787); 
    inet_aton("127.0.0.1", &addr.sin_addr); 
    printf("->:"); 
    gets(buffer); 
    sendto (sd, buffer , 15, 0 ,(struct sockaddr *)&addr, sizeof(addr)); 
    do{ 
     addr_len = sizeof(addr); 
     setsockopt(sd, SOL_SOCKET, SO_RCVBUF, &a, sizeof(int)); 

     bytes = recvfrom(sd, buffer, 2048, MSG_WAITALL,,(struct sockaddr *) &addr, &addr_len); 
     if(bytes>0){ 
       printf("Mensaje de %s: %d (%d bytes)\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), bytes); 

       printf("el mensaje dice :"); 
       puts(buffer); 
       printf("-:"); 
       gets(buffer); 
       sendto (sd, buffer , 15, 0 ,(struct sockaddr *)&addr, sizeof(addr)); 

     } 

    }while(1); 

    return 0; 
} 

serverUDP.c

#include <sys/socket.h> 
#include <string.h> 
#include <netinet/in.h> 
#include <stdio.h> 
#include <arpa/inet.h> 

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

    struct sockaddr_in addr; 
    int sd; 
    int bytes, reply_len, addr_len; 
    char buffer[2048]; 
    sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 
    int a = 65535; 

    bzero(&addr, sizeof(addr)); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(8787); 
    addr.sin_addr.s_addr = INADDR_ANY; 
    if(bind(sd,(struct sockaddr *) &addr, sizeof(addr)) != 0){ 
    printf("Error en BIND\n"); 
    } 
    do { 
     addr_len = sizeof(addr); 

     bytes = recvfrom(sd, buffer, 2048, MSG_WAITALL,(struct sockaddr *) &addr, &addr_len); 
     setsockopt(sd, SOL_SOCKET, SO_RCVBUF, &a, sizeof(int)); 
     if(bytes>0){ 
    printf("Mensaje de %s: %d (%d bytes)\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), bytes); 
    printf("el mensaje dice :"); 
    puts(buffer); 
    printf("-:"); 
    gets(buffer); 
     sendto (sd, buffer , 15, 0 ,(struct sockaddr *)&addr, sizeof(addr)); 

     } 
    }while(1); 
} 
+4

Может звучать как глупый вопрос, но уверены ли вы, что на самом деле вы должны получать больше? Что говорит wirecark о пакетах? – Timbo

+1

Вы пытались добавить 'MSG_WAITALL' к флагам? – Nemo

+0

Его строка, полученная с помощью gets, я добавил bytes = recvfrom (sd, buffer, 2048, MSG_WAITALL, (struct sockaddr *) & addr, & addr_len); но то же самое, его как приложение чата –

ответ

3

UDP это сообщение на основе, в отличие от TCP, который на основе потока. recv/from() не может получать частичные данные UDP, чтение - все или ничего. Если вы передаете буфер с 2048 байтами и recv/from() сообщает, что 15 байтов были прочитаны, тогда полезная нагрузка UDP-сообщения действительно была размером 15 байт. Вы можете использовать сниффер пакетов, например Wireshark, для проверки этого.

+1

Это не entirley все или ничего, если вы передадите размер буфера меньше фактического пакета, вы получите усеченный пакет – nos

+0

мою ошибку, я положил 15 в sendto fuction длина выглядит код –

1

Был мой mystake я не знаю, почему я поставил 15 в функции SENDTO, поэтому только 15bytes данных было отослано ... XD

sendto (sd, buffer , 15, 0 ,(struct sockaddr *)&addr, sizeof(addr)); 

решается увеличением от 15 до 2048

Смежные вопросы