2014-01-19 95 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

可能聽起來像一個愚蠢的問題,但你確定你實際上應該得到更多? wireshark對數據包有什麼看法? – Timbo

+1

您是否曾嘗試在標誌中添加MSG_WAITALL? – Nemo

+0

它獲得一個字符串,我已經添加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函數長度看代碼 –

1

是我mystake我不知道爲什麼我在sendto函數將15個,所以只有數據的15bytes是sended ... XD

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

解決增加15至2048