0
모든 인터페이스에서 IPv4 및 IPv6을 모두 허용하는 서버를 만들고 싶습니다.다중 클라이언트 서버, 다중 인터페이스, 다중 IP 버전 소켓
localhost, 127.0.0.1, :: 1, 192.168.1.26을 포함한 모든 주소에서 작동하지 않는 것 같습니다. 내가 무엇이 누락 되었습니까?
getaddrinfo(3)에 따르면, ai_family가 AI_PASSIVE 플래그로 설정되기 때문에. 여기에 지금까지 내 코드입니다
'반환 소켓 주소는 "와일드 카드 주소를"포함됩니다'.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/times.h>
#include <errno.h>
#define MAXBUF 1024
const char* PORTNUM = "687";
int init_address(struct addrinfo* hints)
{
hints->ai_flags= AI_PASSIVE;
hints->ai_family= AF_UNSPEC;
hints->ai_socktype= SOCK_DGRAM;
hints->ai_protocol= IPPROTO_UDP;
return 1;
}
socklen_t init_socket(struct addrinfo* res, int* sockfd)
{
struct addrinfo* ressave;
struct sockaddr_in* all_interface;
socklen_t addrlength;
ressave=res;
all_interface = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
do {/* each of the returned IP address is tried*/
(*sockfd) = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if ((*sockfd)<0)
continue; /* fail, try next one*/
if (bind((*sockfd), (struct sockaddr*)all_interface, sizeof(all_interface)) == 0)
break; /*success*/
close(*sockfd);
}while(res->ai_next != NULL && (res = res->ai_next)!= NULL);
if(&addrlength)
addrlength = res->ai_addrlen;
freeaddrinfo(ressave);
free(all_interface);
return addrlength;
}
int doprocessing(char* buffer, size_t buff_size)
{
return 0;
}
int peak_data(char* buffer, size_t buff_size)
{
return 0;
}
int main(int argc, char const *argv[])
{
int sockfd, newsockfd;
int bytes_read;
char* port;
char buffer[MAXBUF];
pid_t pid;
socklen_t addrlen, len;
struct addrinfo* socket_info;
struct addrinfo* res;
struct addrinfo* backup_res;
struct sockaddr* cliaddr;
int n;
socket_info = (struct addrinfo*)malloc(sizeof(struct addrinfo));
res = (struct addrinfo*)malloc(sizeof(struct addrinfo));
memset(socket_info, 0, sizeof(struct addrinfo));
init_address(socket_info);
if((n = getaddrinfo(NULL, PORTNUM, socket_info, &res)) !=0)
{
printf("multi_server: error for %s: %s", PORTNUM, gai_strerror(n));
exit(0);
}
if ((addrlen = init_socket(res, &sockfd)) < 0)
{
printf("multi_server: Socket or Bind error");
exit(0);
}
free(socket_info);
cliaddr=malloc(addrlen);
len=addrlen;
printf("\nUDP Server: waiting for connection...");
while (1) {
bytes_read = recvfrom(sockfd, buffer, MAXBUF-1, MSG_PEEK, cliaddr, &len);
if (bytes_read > 0) {
// a connection has been established
buffer[MAXBUF] = '\0';
printf("\nUDP Server: received %d bytes ", bytes_read);
pid = fork();
if (pid < 0) {
perror("UDP Server: ERROR while forking new process.\n");
exit(1);
}
// check if the process ID is zero
if (pid == 0) {
// we are now inside the new forked process
if(peak_data(buffer, bytes_read))
{
doprocessing(buffer, bytes_read);
}
printf("Now in %d\n", pid);
close(sockfd);
exit(0);
}
}
}
}
IPV6_V6ONLY 모드를 비활성화하고 IPv6을 허용하려면 Windows에서 setsockopt (my_sock, IPPROTO_IPV6, IPV6_V6ONLY, &val); (여기서 val은 0 값의 정수 변수))를 수행해야합니다. 소켓도 IPv4 연결로 작동합니다. –
죄송합니다. 작동하지 않는 것을 의미합니다. – GeneralZero
@JeremyFriesner는 방화벽을 해제하고 낮은 포트 번호부터 루트로 실행하는 것을 잊어 버렸습니다. – GeneralZero