Переписать TCP клиент-сервер с IPv4 на IPv6
Я пытаюсь переписать свою программу, чтобы клиент с сервером взаимодействовали по IPv6 . Все скомпилировалось вроде бы корректно.Сервер запустился, но при попытке подключить клиента к серверу выдает connect: Network is unreachable Подскажите, пожалуйста. в чем может быть проблема и как её исправить?
сервер:
#include <stdio.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#define BUFLEN 512
#define MAXLINE 255
char str_addr[INET6_ADDRSTRLEN];
char point [9]={'1','2','3','4','5','6','7','8','9'};
char *my_itoa(int num, char *str)
{
if(str == NULL)
{
return NULL;
}
sprintf(str, "%d", num);
return str;
}
//#ifdef MUTEX
pthread_mutex_t lock;
//#endif
void *tcp_work(void *);
int check ()
{
if (((*point=='X')&&(*(point+1)=='X')&&(*(point+2)=='X'))||((*(point+3)=='X')&&(*(point+4)=='X')&&(*(point+5)=='X'))||((*(point+6)=='X')&&(*(point+7)=='X')&&(*(point+8)=='X'))||((*point=='X')&&(*(point+3)=='X')&&(*(point+6)=='X'))||((*(point+1)=='X')&&(*(point+4)=='X')&&(*(point+7)=='X'))||((*(point+2)=='X')&&(*(point+5)=='X')&&(*(point+8)=='X'))||((*point=='X')&&(*(point+4)=='X')&&(*(point+8)=='X'))||((*(point+2)=='X')&&(*(point+4)=='X')&&(*(point+6)=='X')))
{ return 1;}
else if (((*point=='O')&&(*(point+1)=='O')&&(*(point+2)=='O'))||((*(point+3)=='O')&&(*(point+4)=='O')&&(*(point+5)=='O'))||((*(point+6)=='O')&&(*(point+7)=='O')&&(*(point+8)=='O'))||((*point=='O')&&(*(point+3)=='O')&&(*(point+6)=='O'))||((*(point+1)=='O')&&(*(point+4)=='O')&&(*(point+7)=='O'))||((*(point+2)=='O')&&(*(point+5)=='O')&&(*(point+8)=='O'))||((*point=='O')&&(*(point+4)=='O')&&(*(point+8)=='O'))||((*(point+2)=='O')&&(*(point+4)=='O')&&(*(point+6)=='O')))
{ return 2;}
if (((*point=='X')||(*point=='O'))&&((*(point+1)=='X')||(*(point+1)=='O'))&&((*(point+2)=='X')||(*(point+2)=='O'))&&((*(point+3)=='X')||(*(point+3)=='O'))&&((*(point+4)=='X')||(*(point+4)=='O'))&&((*(point+5)=='X')||(*(point+5)=='O'))&&((*(point+6)=='X')||(*(point+6)=='O'))&&((*(point+7)=='X')||(*(point+7)=='O'))&&((*(point+8)=='X')||(*(point+8)=='O')))
{ return 3;}
return 0;
}
int g_port;
struct s_Data{
char filename[50];
char data[MAXLINE];
int number;
int flag;
}sendData, recvData;
void reaper(int sig)
{
int status;
while(wait3(&status, WNOHANG, (struct rusage *)0) >= 0);
}
int MAX (int x, int y)
{
if (x>y)
return x;
else
return y;
}
int create_tcp()
{
int sockfd;
struct sockaddr_in6 servaddr,clientaddr;
if((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0)
{
perror("Error open Socket.");
exit(1);
}
bzero(&servaddr, sizeof(servaddr));
bzero(&clientaddr, sizeof(clientaddr));
servaddr.sin6_family = AF_INET6;
servaddr.sin6_addr = in6addr_any;
// inet_pton(AF_INET6, in6addr_any, &servaddr.sin6_addr.s6_addr);
servaddr.sin6_port = htons(g_port);
socklen_t len;
if(bind(sockfd, (struct sockaddr *)& servaddr, sizeof(servaddr)) < 0)
{
perror("bind server error");
exit(2);
}
else{
printf("Server TCP : bind() successful\n");
len = sizeof(servaddr);
if (getsockname(sockfd,(struct sockaddr*) &servaddr, &len)==-1)
perror("getsockname");
else
printf("Port number %d\n", ntohs(servaddr.sin6_port));
}
len = sizeof(servaddr);
if(getsockname(sockfd, (struct sockaddr *)&servaddr, &len) < -1)
{
perror("getsockname error.\n");
exit(1);
}
if(listen(sockfd, 5) < 0)
{
perror("Error on listen.\n");
exit(1);
}
return sockfd;
}
int main(int argc, char **argv)
{
int newsockfd;
fd_set rdfs;
int tsock, usock;
int fd, ndfs;
struct sockaddr_in6 client_tcp;
int childpid;
tsock = create_tcp();
bzero(&client_tcp, sizeof(client_tcp));
socklen_t clientlen_tcp;
bzero(&sendData, sizeof(sendData));
bzero(&recvData, sizeof(recvData));
clientlen_tcp = sizeof(client_tcp);
signal(SIGCHLD, reaper);
ndfs = tsock+1;
FD_ZERO(&rdfs);
pthread_t thread_id;
signal(SIGCHLD, reaper);
while(1)
{
FD_SET(tsock, &rdfs);
if(select(ndfs, &rdfs, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0)
{
perror("Select on error.\n");
exit(1);
}
if(FD_ISSET(tsock, &rdfs))
{
newsockfd = accept(tsock, (struct sockaddr *) &client_tcp, &clientlen_tcp);
if(newsockfd < 0)
{
perror("Error on accept.\n");
exit(1);
}
pthread_mutex_init (&lock, NULL);
if( pthread_create( &thread_id , NULL , tcp_work , (void *) &newsockfd) < 0)
{
perror("could not create thread");
return 1;
}
puts("TCP client connected");
if (newsockfd < 0)
{
perror("accept failed");
return 1;
}
pthread_mutex_destroy(&lock);
}
FD_ZERO(&rdfs);
}
}
void *tcp_work(void *socket_desc)
{
int sock = *(int*)socket_desc;
int count = 1; int bytes_read = 0;
int Mx = 255;
char data[Mx];
char buf1[] = "1";
char num[50];
char exit[] = "exit";
struct s_Data recvData;
bzero(&recvData, sizeof(recvData));
while(1)
{
bytes_read = recv(sock, &num, sizeof(num), 0);
printf("%s", num);
if(bytes_read > 0)
{
pthread_mutex_lock (&lock);
num[50] = '\0';
point[atoi(num)-1] = 'X';
if (check()>0)
{
send(sock,&exit,sizeof(exit),0);
}
else{
srand(time(0));
int i;
i = 1+rand()%9;
do {
i = 1+rand()%9;
}while(point[i-1]=='X'||point[i-1]=='O');
point[i-1] = 'O';
send(sock,my_itoa(i,num),sizeof(num),0);
}
pthread_mutex_unlock (&lock);
}
else break;
}
return 0;
}
pthread_mutex_unlock (&lock);
}
else break;
}
return 0;
}
Клиент:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
//static const uint8_t myaddr[16] = { 0x20, 0x01, 0x08, 0x88, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 };
char num[50];
char message[] = "Hello";
char point [9]={'1','2','3','4','5','6','7','8','9'};
int check ();
void show();
int check ()
{
if (((*point=='X')&&(*(point+1)=='X')&&(*(point+2)=='X'))||((*(point+3)=='X')&&(*(point+4)=='X')&&(*(point+5)=='X'))||((*(point+6)=='X')&&(*(point+7)=='X')&&(*(point+8)=='X'))||((*point=='X')&&(*(point+3)=='X')&&(*(point+6)=='X'))||((*(point+1)=='X')&&(*(point+4)=='X')&&(*(point+7)=='X'))||((*(point+2)=='X')&&(*(point+5)=='X')&&(*(point+8)=='X'))||((*point=='X')&&(*(point+4)=='X')&&(*(point+8)=='X'))||((*(point+2)=='X')&&(*(point+4)=='X')&&(*(point+6)=='X')))
{printf(" \nX wins!"); return 1;}
else if (((*point=='O')&&(*(point+1)=='O')&&(*(point+2)=='O'))||((*(point+3)=='O')&&(*(point+4)=='O')&&(*(point+5)=='O'))||((*(point+6)=='O')&&(*(point+7)=='O')&&(*(point+8)=='O'))||((*point=='O')&&(*(point+3)=='O')&&(*(point+6)=='O'))||((*(point+1)=='O')&&(*(point+4)=='O')&&(*(point+7)=='O'))||((*(point+2)=='O')&&(*(point+5)=='O')&&(*(point+8)=='O'))||((*point=='O')&&(*(point+4)=='O')&&(*(point+8)=='O'))||((*(point+2)=='O')&&(*(point+4)=='O')&&(*(point+6)=='O')))
{printf("\nO wins!"); return 1;}
if (((*point=='X')||(*point=='O'))&&((*(point+1)=='X')||(*(point+1)=='O'))&&((*(point+2)=='X')||(*(point+2)=='O'))&&((*(point+3)=='X')||(*(point+3)=='O'))&&((*(point+4)=='X')||(*(point+4)=='O'))&&((*(point+5)=='X')||(*(point+5)=='O'))&&((*(point+6)=='X')||(*(point+6)=='O'))&&((*(point+7)=='X')||(*(point+7)=='O'))&&((*(point+8)=='X')||(*(point+8)=='O')))
{printf("\ndraw!"); return 1;}
return 0;
}
void show()
{
int j=0;
for (int i=0;i<9;i++)
{
printf("%c ",*(point+i));
j++;
if (j==3) {j=0; printf("\n");}
}
}
int main(int argc, char *argv[])
{
int sock;
struct sockaddr_in6 addr;
void sigalarm(int);
if(argc!=2) {
printf("Вы забыли указать адрес и порт.\n");
exit(1);
}
sock = socket(AF_INET6, SOCK_STREAM, 0);
if(sock < 0)
{
perror("socket");
exit(1);
}
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(atoi(argv[1]));
// addr.sin6_addr = "::1/128";//inet_addr(argv[1]);
inet_pton(AF_INET6, "::1/128", &addr.sin6_addr);
// memcpy(addr.sin6_addr.s6_addr, myaddr, sizeof myaddr);
if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
perror("connect");
exit(2);
}
show();
while(1)
{
scanf ("%s", num);
point[atoi(num)-1] = 'X';
//show();
check();
send(sock, num, sizeof(num), 0);
recv(sock, num, sizeof(num), 0);
if(num[0] == 'e')
{
check();
break;
}
else{point[atoi(num)-1] = 'O';
show();
check();
}
}
close(sock);
return 0;
}