2009-05-28 52 views
2

我發現了一個很好的抽象,我可以使用FILE從UDP讀取數據。這對於讀取數據非常有用,但是我無法通過UDP來傳遞數據。下面是在文件流的UDP數據讀取的代碼爲:使用FILE流在c中讀取/寫入套接字

u_int8 *buf; 
int sockfd = socket(AF_INET, SOCK_DGRAM, 0); 
struct sockaddr_in serverAddr; 
if (sockfd < 0) { 
    printf("Could not open socket\n"); 
    exit(1); 
} 
buf = malloc(BUF_SIZE * sizeof(u_int8)); 
serverAddr.sin_family = AF_INET; 
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); 
serverAddr.sin_port = htons(port); 
int rc = bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); 
if (rc<0) { 
    printf("Could not bind to port %d\n", port); 
    exit(1); 
} 
/* Make sockfd blocking */ 
int flags = fcntl(sockfd, F_GETFL, 0); 
fcntl(sockfd, F_SETFL, flags & ~O_NONBLOCK); 

FILE *sockfile; 
sockfile = (FILE*)fdopen(sockfd, "r"); 

現在一些其他的代碼可以調用:

fread(data, sizeof(u_int8), frame_payload_size, sockfile); 

這工作得很好。但是,反過來似乎並不:

u_int8 *buf; 
int sockfd = socket(AF_INET, SOCK_DGRAM, 0); 
struct sockaddr_in clientAddr; 
if (sockfd < 0) { 
    printf("Could not open socket\n"); 
    exit(1); 
} 
memset((char *)&clientAddr, 0, sizeof(clientAddr)); 
buf = malloc(BUF_SIZE * sizeof(u_int8)); 
clientAddr.sin_family = AF_INET; 
clientAddr.sin_port = htons(port); 
if (inet_aton("127.0.0.1", &clientAddr.sin_addr)==0) { 
    printf("inet_aton()\n"); 
    abort(); 
} 
int rc = bind(sockfd, (struct sockaddr *)&clientAddr, sizeof(clientAddr)); 
FILE *sockfile; 
sockfile = (FILE*)fdopen(sockfd, "w"); 

一些其他的代碼調用:

written = fwrite(fm->frame, sizeof(u_int8), fm->frame_length, data_out_stream); 

「寫」將返回寫入元素的正數,但沒有UDP數據包似乎產生。

正在嘗試做什麼?任何建議,爲什麼它可能不工作?

回答

1

刷新FILE。只有在網絡數據包已滿或者強制刷新時纔會生成網絡數據包。因此,除非您寫入超過1500個字節(默認值,包括標題字段),否則計算機將等待交付。

1

你沒有隱藏信息,這可能很酷,但是你給了另一段代碼的錯誤信息,也就是說你的套接字的行爲就像一個流。我認爲你應該堅持讀/寫呼叫,否則你會發現自己有一個leaky abstraction

1

這其實很奇怪。使用fflush(),或者更好一些,使用send()而不是fwrite()並且丟棄FILE。由於FILE對象如何緩衝的語義以及數據報如何保證不按順序到達/到達,您將遇到意外的行爲,這可能會導致出現亂碼消息。除非你使用UNIX套接字。