2012-02-10 51 views
0

使用sendto()將UDP數據包發送到主機時會發生什麼情況。我發送的所有比特都被髮送(從返回值中知道)。我立即使用recvfrom(),它不輸出任何內容,但程序不退出(即不返回值)。使用UDP進行網絡處理

我認爲如果沒有收到回覆,程序必須退出。

對端口的UDP數據包的回覆是什麼。

這個包是被防火牆攔截的?如果是,那麼爲什麼sendto的返回值是非負的。

+0

你能分享一下你想做什麼嗎?你是否證實UDP是你想使用的協議? – bitops 2012-02-10 19:52:29

回答

0

recvfrom()將阻塞,直到收到一條消息,除非您將套接字設置爲非阻塞。

要查找的接口

  • ioctl()FIONBIOO_NONBLOCK(根據您的平臺),
  • select()等待數據的到達,超時一段時間後

另請注意,sendto()的地址和端口號通常爲網絡字節順序,因此請查看ntohlntohs

0

您必須在客戶端或服務器中出現錯誤。首先嚐試使用localhost,這樣可以避免出現防火牆問題

這是一個非阻塞udp客戶端/服務器的示例,我用它來測試,它使用ioctl()檢查是否有數據要讀取到套接字上,但是如果你想用epoll的效率會比較高,你也可以指定超時微秒等待做一些重要的應用程序:

[[email protected] tests]$ cat udpserv.c 
#include <stdlib.h> 
#include <fcntl.h> 
#include <sys/ioctl.h> 
#include <string.h> 
#include <arpa/inet.h> 
#include <netinet/in.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <unistd.h> 
#include <errno.h> 

#define BUFLEN 512 
#define NPACK 15 
#define PORT 9930 

void diep(char *s) 
{ 
    printf("erno=%d errstr=%s\n",errno,strerror(errno)); 
    perror(s); 
    exit(1); 
} 

int main(void) 
{ 
    struct sockaddr_in si_me, si_other; 
    int s,ret,nbytes, i, slen=sizeof(si_other); 
    char buf[BUFLEN]; 

    if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) 
    diep("socket"); 

    memset((char *) &si_me, 0, sizeof(si_me)); 
    si_me.sin_family = AF_INET; 
    si_me.sin_port = htons(PORT); 
    si_me.sin_addr.s_addr = htonl(INADDR_ANY); 
    if (bind(s, (struct sockaddr*) &si_me, sizeof(si_me))==-1) 
     diep("bind"); 

    fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0) | O_NONBLOCK); 
    sleep(10); 
    for (i=0; i<NPACK; i++) { 
    ret=ioctl(s,FIONREAD,&nbytes); 
    if (ret==-1) { 
     printf("error on FIONREAD\n"); 
    } else { 
     printf("nbytes=%d\n",nbytes); 
    } 
    if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr*) &si_other, &slen)==-1) 
     diep("recvfrom()"); 
    printf("Received first half of packet from %s:%d\nData: %s\n\n", 
      inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf); 
    } 

    close(s); 
    return 0; 

} 



[[email protected] tests]$ cat udpclient.c 
#include <stdlib.h> 
#include <string.h> 
#include <arpa/inet.h> 
#include <netinet/in.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <unistd.h> 

#define SRV_IP "127.0.0.1" 
#define BUFLEN 200 
#define NPACK 10 
#define PORT 9930 

/* diep(), #includes and #defines like in the server */ 
void diep(char *s) 
{ 
    perror(s); 
    exit(1); 
} 

int main(void) 
{ 
    struct sockaddr_in si_other; 
    int s, i, slen=sizeof(si_other); 
    char buf[BUFLEN]; 

    if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) 
    diep("socket"); 

    memset((char *) &si_other, 0, sizeof(si_other)); 
    si_other.sin_family = AF_INET; 
    si_other.sin_port = htons(PORT); 
    if (inet_aton(SRV_IP, &si_other.sin_addr)==0) { 
    fprintf(stderr, "inet_aton() failed\n"); 
    exit(1); 
} 

for (i=0; i<NPACK; i++) { 
    printf("Sending packet %d\n", i); 
    sprintf(buf, "This is packet %d\n", i); 
    if (sendto(s, buf, BUFLEN, 0, (struct sockaddr*) &si_other, slen)==-1) 
     diep("sendto()"); 
} 

close(s); 
return 0; 
} 

和sendto()是非負的,因爲它返回發送的字節數。檢查sendto的手冊頁