2009-05-28 6 views
2

J'ai découvert une belle abstraction dans laquelle je peux lire des données d'UDP en utilisant un FICHIER. Cela fonctionne très bien pour lire des données, mais je ne peux pas le faire fonctionner pour cracher des données sur UDP. Voici le code pour la lecture des données UDP sur un flux de fichier:Lecture/écriture dans une socket en utilisant un flux FILE dans 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"); 

Maintenant, un autre code peut appeler:

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

Cela fonctionne très bien. Cependant, l'inverse ne semble pas:

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"); 

Certains autre code appellera:

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

« écrit » renverra un nombre positif d'éléments écrits, mais aucun paquet UDP semble être généré .

Est ce que j'essaye de faire possible? Des suggestions pour expliquer pourquoi cela ne fonctionne peut-être pas?

Répondre

1

Vider le fichier. Les paquets réseau ne sont générés que lorsqu'ils sont pleins ou lorsque vous forcez un flush. Donc, sauf si vous écrivez plus de 1500 octets (la valeur par défaut, y compris les champs d'en-tête), l'ordinateur attendra la livraison.

1

Vous ne cachez pas d'informations, ce qui peut être cool, mais vous donnez de fausses informations à l'autre partie du code, c'est-à-dire que votre socket se comporte comme un flux. Je pense que vous devriez coller avec appel en lecture/écriture, ou vous vous trouverez avec un leaky abstraction

1

C'est en fait assez bizarre. Utilisez fflush(), ou mieux encore, utilisez send() au lieu de fwrite() et fossé le FICHIER. Vous rencontrerez un comportement inattendu en raison de la sémantique de la façon dont les objets FILE sont mis en mémoire tampon et comment les datagrammes ne sont pas garantis d'arriver dans l'ordre/arriver à tous, cela peut entraîner des messages brouillés. Sauf si vous utilisez des sockets UNIX.

Questions connexes