#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main()
{
struct sockaddr_in addr;
int fd, cnt,ret;
char ch = 'y',msg[] ="How are you";
if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
printf("Error: socket");
exit(1);
}
printf("\nDone socket\n");
/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr("128.88.143.113");
addr.sin_port=htons(9090);
ret=connect(fd,(struct sockaddr *)&addr,sizeof(addr));
perror("Connect:");
while(ch == 'y'){
cnt = send(fd,msg,sizeof(msg),0);
if(cnt < 0)
perror("send:");
printf("\nNumber of bytes sent = %d , \n",cnt);
printf("Continue (y/n)\n");
scanf(" %c",&ch);
}
return 0;
}
El código anterior se compila para ejecutarse en una máquina Linux.UDP enviar comportamiento después de conectar()
Supongamos que el código anterior envía datos a una máquina en la dirección IP 128.88.143.113
. Ningún socket UDP está vinculado al puerto 9090
en 128.88.143.113
.
En el bucle while
, la primera llamada a send()
tiene éxito (el paquete pasa en realidad en el cable; comprobó usando trace
) y el segundo send()
falla con Connection refused
. El third send()
tiene éxito y el cuarto falla, y así sucesivamente.
Sospecho que después de la primera send()
la pila recibe un mensaje de error ICMP (visto en tcpdump
en la máquina Linux) que se guarda en la estructura del socket. El segundo send()
falla al ver este error y no se envía realmente ningún paquete. El segundo send()
también borra el error en la estructura del socket. Por lo tanto, el tercero send()
tiene éxito y el cuarto falla, y así sucesivamente.
Preguntas:
- es correcta esta suposición?
- ¿Cuál debería ser el comportamiento correcto? ¿Existe algún estándar de RFC que defina dicho comportamiento?
- Dado que UDP no mantiene ningún estado de conexión, ¿no debería tener éxito cada
send()
?
Veo un comportamiento similar en una máquina arch Linux cuando se envía a través de una interfaz de alias. ¿Esto fue resuelto? –