제12장 IPv4와 IPv6의 상호 운용성

3784 단어
이 장에서 달성하고자 하는 목표는 IPv4와 IPv6 서버와 클라이언트가 어떤 상황에서 통신할 수 있는지 이해하는 것이다.
어떤 상황에서 통신이 안 되고, 수업 후의 그 프로그래밍 문제를 완성할 수 있습니까?
  • 양쪽은 모두 단일 창고 호스트이고 하나의 IPv4, 하나의 IPv6는 각각 클라이언트와 서버로 통신할 수 없다.
  • IPv6 서버 단일 스택 호스트와 IPv4 고객 이중 스택 호스트가 통신할 수 없는데 어떻게 된 일입니까?IPv4 고객이 IPv4 데이터 보고서를 보내면 이중 스택에서 IPv6 데이터 보고서로 전환할 수 없습니까?
  • IPv4 서버 단일 스택 호스트와 IPv6 클라이언트 이중 스택 호스트는 통신할 수 없습니다. 이것은?2중의 문제와 같을 거예요. 다시 자세히 봐야겠어요.자동 변환 기능이 없나요?

  • 그리고 수업 후의 12.2 문제를 실현하고 테스트를 통해 동시에 사용할 수 없습니다. 오류는 다음과 같습니다.
    bind() error: Address already in use

    먼저 ip4tcp.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <errno.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #define PORT 9999
    #define LISTENQ 5
    int main(int argc, char *argv[])
    {
        if (argc != 2) {
            printf("Usage: %s <IP>
    ", argv[0]);         exit(0);     }
        int listenfd;
        struct sockaddr_in servaddr;
        if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
            printf("socket() error: %s
    ", strerror(errno));         exit(1);     }
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(PORT);
        if ((inet_pton(AF_INET, argv[1], &servaddr.sin_addr)) <= 0) {
            printf("inet_pton() error: %s
    ", strerror(errno));         exit(1);     }
        if ((bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr))) == -1) {
            printf("bind() error: %s
    ", strerror(errno));         exit(1);     }
        if ((listen(listenfd, LISTENQ)) == -1) {
            printf("listen() error: %s
    ", strerror(errno));         exit(1);     }
        pause();
        return 0;
    }

    지금은 ip6tcp입니다.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <errno.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #define PORT 9999
    #define LISTENQ 5
    int main(int argc, char *argv[])
    {
        if (argc != 2) {
            printf("Usage: %s <IP6>
    ", argv[0]);         exit(0);     }
        int listenfd;
        struct sockaddr_in6 servaddr;
        if ((listenfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) {
            printf("socket() error: %s
    ", strerror(errno));         exit(1);     }
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin6_family = AF_INET6;
        servaddr.sin6_port = htons(PORT);
        if ((inet_pton(AF_INET6, argv[1], &servaddr.sin6_addr)) <= 0) {
            printf("inet_pton() error: %s
    ", strerror(errno));         exit(1);     }
        if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
            printf("bind() error: %s
    ", strerror(errno));         exit(1);     }
        if (listen(listenfd, LISTENQ) < 0) {
            printf("listen() error: %s
    ", strerror(errno));         exit(1);     }
        pause();
        return 0;
    }

    socket 다음에 setsockopt를 사용하여 SO_ 설정REUSEADDR 옵션은 두 개도 열 수 없습니다.
      int reuseaddr_true = 1;
      if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_true, sizeof(reuseaddr_true)) == -1) {
            printf("setsockopt() error: %s
    ", strerror(errno));         exit(1);     }

    좋은 웹페이지 즐겨찾기