It seems that the stream does not go in the for loop containing accept in ipv6server.c and therefore cannot accept and connect to the client. What mistake? This code works fine for IPV4, but after changing IPV6 this problem occurs
ipv6server.c
#include <stdio.h>
#include <stdlib.h> /* needed for os x */
#include <string.h> /* for memset */
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/errno.h> /* defines ERESTART, EINTR */
#include <sys/wait.h> /* defines WNOHANG, for wait() */
#include "port.h"
#ifndef ERESTART
#define ERESTART EINTR
#endif
extern int errno;
void serve(int port);
void disconn(void);
main(int argc, char **argv)
{
extern char *optarg;
extern int optind;
int c, err = 0;
int port = SERVICE_PORT;
static char usage[] = "usage: %s [-d] [-p port]\n";
while ((c = getopt(argc, argv, "dp:")) != -1)
switch (c) {
case 'p':
port = atoi(optarg);
if (port < 1024 || port > 65535) {
fprintf(stderr, "invalid port number: %s\n", optarg);
err = 1;
}
break;
case '?':
err = 1;
break;
}
if (err || (optind < argc)) {
fprintf(stderr, usage, argv[0]);
exit(1);
}
serve(port);
}
void
serve(int port)
{
int svc;
int rqst;
socklen_t alen;
struct sockaddr_in6 my_addr;
struct sockaddr_in6 client_addr;
int sockoptval = 1;
char hostname[128];
gethostname(hostname, 128);
if ((svc = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
perror("cannot create socket");
exit(1);
}
setsockopt(svc, SOL_SOCKET, SO_REUSEADDR, &sockoptval, sizeof(int));
memset((char*)&my_addr, 0, sizeof(my_addr));
my_addr.sin6_family = AF_INET6;
my_addr.sin6_port = htons(port);
my_addr.sin6_addr = in6addr_any;
client_addr.sin6_family = AF_INET6;
client_addr.sin6_port = htons(port);
client_addr.sin6_addr = in6addr_any;
if (bind(svc, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0) {
perror("bind failed");
exit(1);
}
if (listen(svc, 5) < 0) {
perror("listen failed");
exit(1);
}
printf("server started on %s, listening on port %d\n", hostname, port);
alen = sizeof(client_addr);
for (;;) {
while ((rqst = accept(svc,
(struct sockaddr *)&client_addr, &alen)) < 0) {
if ((errno != ECHILD) && (errno != ERESTART) && (errno != EINTR)) {
perror("accept failed");
exit(1);
}
}
printf("received a connection from: %s port %d\n",
inet_ntoa(client_addr.sin6_addr), ntohs(client_addr.sin6_port));
shutdown(rqst, 2);
}
}
ipv6client.c
#include <stdio.h>
#include <stdlib.h> /* needed for os x*/
#include <string.h> /* for strlen */
#include <netdb.h> /* for gethostbyname() */
#include <sys/socket.h>
#include <netinet/in.h>
#include "port.h"
int conn(char *host, int port);
void disconn(void);
main(int argc, char **argv)
{
extern char *optarg;
extern int optind;
int c, err = 0;
char *prompt = 0;
int port = SERVICE_PORT;
char *host = "localhost";
static char usage[] =
"usage: %s [-d] [-h serverhost] [-p port]\n";
while ((c = getopt(argc, argv, "dh:p:")) != -1)
switch (c) {
case 'h':
host = optarg;
break;
case 'p':
port = atoi(optarg);
if (port < 1024 || port > 65535) {
fprintf(stderr, "invalid port number: %s\n", optarg);
err = 1;
}
break;
case '?':
err = 1;
break;
}
if (err || (optind < argc)) {
fprintf(stderr, usage, argv[0]);
exit(1);
}
printf("connecting to %s, port %d\n", host, port);
if (!conn(host, port))
exit(1);
disconn();
return 0;
}
int fd;
int
conn(char *host, int port)
{
struct hostent *hp;
unsigned int alen;
struct sockaddr_in6 myaddr;
struct sockaddr_in6 servaddr;
printf("conn(host=\"%s\", port=\"%d\")\n", host, port);
if ((fd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
perror("cannot create socket");
return 0;
}
memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin6_family = AF_INET6;
myaddr.sin6_addr = in6addr_any;
myaddr.sin6_port = htons(0);
if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
perror("bind failed");
return 0;
}
alen = sizeof(myaddr);
if (getsockname(fd, (struct sockaddr *)&myaddr, &alen) < 0) {
perror("getsockname failed");
return 0;
}
printf("local port number = %d\n", ntohs(myaddr.sin6_port));
memset((char*)&servaddr, 0, sizeof(servaddr));
servaddr.sin6_family = AF_INET6;
servaddr.sin6_port = htons(port);
hp = gethostbyname(host);
if (!hp) {
fprintf(stderr, "could not obtain address of %s\n", host);
return 0;
}
memcpy((void *)&servaddr.sin6_addr, hp->h_addr_list[0], hp->h_length);
if (connect(fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
perror("connect failed");
return 0;
}
return 1;
}
void
disconn(void)
{
printf("disconn()\n");
shutdown(fd, 2);
}