Reputation: 315
Here is my code.
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <stdio.h>
#include <string.h>
int max(int socket_handle[]);
int main( void )
{
int max_clients_allowed = 2;
int socket_handle[max_clients_allowed];
int client_handle[max_clients_allowed];
struct sockaddr_in6 server_address[max_clients_allowed];
struct sockaddr_in6 client_address[max_clients_allowed];
char buffer[1000];
socklen_t client_length;
fd_set read_handles;
struct timeval timeout_interval;
int bytes_received;
int port_number = 9000;
int retval;
int i;
printf("Hello, human.\n");
for (i = 0; i < max_clients_allowed; i++)
{
printf("Creating socket%d on port: %d\n", i, port_number + i);
socket_handle[i] = socket(PF_INET6,SOCK_DGRAM,0);
memset( &server_address[i], 0, sizeof( server_address[i] ) );
server_address[i].sin6_family = AF_INET6;
server_address[i].sin6_addr=in6addr_any;
server_address[i].sin6_port=htons( port_number + i );
if(bind( socket_handle[i], (struct sockaddr *)&server_address[i], sizeof( server_address[i] )) < 0)
{
perror("Unable to bind.");
return -1;
}
else
{
printf("Bind %d successful.\n", i);
}
}
while (1) {
FD_ZERO(&read_handles);
FD_SET(socket_handle[0], &read_handles);
FD_SET(socket_handle[1], &read_handles);
timeout_interval.tv_sec = 2;
timeout_interval.tv_usec = 500000;
retval = select(max(socket_handle) + 1, &read_handles, NULL, NULL, &timeout_interval);
if (retval == -1)
{
printf("Select error\n");
//error
}
else if ((retval = 0))
{
printf("timeout\n");
}
else
{
//good
client_length = sizeof(struct sockaddr*);
for (i = 0; i < max_clients_allowed; i++)
{
if (FD_ISSET(socket_handle[i], &read_handles))
{
if((bytes_received = recvfrom(socket_handle[i],buffer,sizeof(buffer),0,(struct sockaddr *)&client_address[i], (socklen_t*)&client_length)) < 0)
{
perror("Error in recvfrom.");
break;
}
printf("\nData received:");
printf("\n--------------\n");
printf("%s", buffer);
}
}
}
}
}
int max(int socket_handle[])
{
if (socket_handle[0] > socket_handle[1])
{
return socket_handle[0];
}
return socket_handle[1];
}
This code is supposed to bind to port 9000 and 9001. It them uses select to see which sockets has incoming data, and then prints the message.
I'm assuming it has something to do with my recvfrom function. I've tried playing around with the parameters with no avail.
Another problem might be when I am setting up the sockets, I am using sin6.addr = in6addr_any. I'm pretty sure PF_INET6 and AF_INET6 are right, but that could be an issue too. I've been playing with this for a bit but I can't find the bug. I would be really grateful if someone could point out my mistake so I could fix it. I know I'm on the cusp of getting this finished.
This is a homework problem, the teacher gave us the test program and all it does is simply send a message on port 9000.
Upvotes: 3
Views: 11630
Reputation: 598089
When calling recvfrom()
, you are setting the client_length
to the wrong value on input. It needs to be set to sizeof(client_address[I])
instead. You also need to reset the client_length
each time you call recvfrom()
.
When you print the received buffer
, you need to take bytes_received
into account since the buffer will not be null-terminated (unless the client is sending null-terminated data).
Try this instead:
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <stdio.h>
#include <string.h>
int main( void )
{
int max_servers = 2;
int server_handle[max_servers];
int max_server_handle = 0;
struct sockaddr_in6 server_address[max_servers];
struct sockaddr_in6 client_address[max_servers];
char buffer[1000];
socklen_t client_length;
fd_set read_handles;
struct timeval timeout_interval;
int bytes_received;
int port_number = 9000;
int retval;
int i;
printf("Hello, human.\n");
for (i = 0; i < max_servers; i++)
{
printf("Creating socket %d on port: %d\n", i, port_number + i);
server_handle[i] = socket(PF_INET6, SOCK_DGRAM, 0);
if (server_handle[i] < 0)
{
perror("Unable to create socket.");
return -1;
}
if (server_handle[i] > max_server_handle)
max_server_handle = server_handle[i];
memset( &server_address[i], 0, sizeof( server_address[i] ) );
server_address[i].sin6_family = AF_INET6;
server_address[i].sin6_addr = in6addr_any;
server_address[i].sin6_port = htons( port_number + i );
if (bind( server_handle[i], (struct sockaddr *)&server_address[i], sizeof( server_address[i] )) < 0)
{
perror("Unable to bind.");
return -1;
}
printf("Bind %d successful.\n", i);
}
while (1)
{
FD_ZERO(&read_handles);
for (i = 0; i < max_servers; i++)
FD_SET(server_handle[i], &read_handles);
timeout_interval.tv_sec = 2;
timeout_interval.tv_usec = 500000;
retval = select(max_server_handle + 1, &read_handles, NULL, NULL, &timeout_interval);
if (retval == -1)
{
printf("Select error\n");
//error
}
else if (retval == 0)
{
printf("timeout\n");
}
else
{
//good
for (i = 0; i < max_servers; i++)
{
if (FD_ISSET(server_handle[i], &read_handles))
{
client_length = sizeof(client_address[i]);
if ((bytes_received = recvfrom(server_handle[i], buffer, sizeof(buffer), 0, (struct sockaddr *)&client_address[i], &client_length)) < 0)
{
perror("Error in recvfrom.");
break;
}
printf("\nData received on socket %d:", i);
printf("\n--------------\n");
printf("%.*s", bytes_received, buffer);
}
}
}
}
}
Upvotes: 2