I'm programming a server-client program. On the server I manage the clients through an array of this data structure:
struct Client
{
struct sockaddr_in addr;
/*...*/
};
struct Client CLIENTS[MAX_CLI];
When I receive the first packet from the client through my UDP
socket
struct sockaddr_in addr_cli;
memset(&addr_cli,0,sizeof(struct sockaddr_in));
b=recvfrom(SOCK_UDP_FATHER, &pdu, sizeof(pdu), MSG_DONTWAIT,
(struct sockaddr *)&addr_cli, (socklen_t *)&laddr_cli);
I want to copy his address to my struct. So I do:
memcpy(&CLIENTS[client].addr,(struct sockaddr*)&addr_cli,
sizeof(struct sockaddr_in));
printf("IP client: %s",inet_ntoa(CLIENTS[client].addr.sin_addr);
The strange thing is that the first try of communication fails, printing 0.0.0.0
. But the next try that the client does, is successful and everything goes fine. Why that happens?
The addr_cli
was not filled by the call to recvfrom
. The last two arguments of recvfrom
are a little bit tricky. They are
struct sockaddr *src_addr,
socklen_t *addrlen
If src_addr
is not NULL, the recvfrom
expects that addrlen
points to the length of src_addr
buffer. (Normally it is the size of sockaddr
structure). If the value of addrlen
is too small, the returned address will be truncated. After the call to recvfrom
the addrlen
will be set to the actual address length. Look at documentation for details.
So you need to initialize laddr_cli
before calling recvfrom()
:
struct sockaddr_in addr_cli;
socklen_t laddr_cli = sizeof(addr_cli); // <--
memset(&addr_cli,0,laddr_cli);
b=recvfrom(SOCK_UDP_FATHER, &pdu, sizeof(pdu), MSG_DONTWAIT,
(struct sockaddr *)&addr_cli, &laddr_cli);