Unix C Inte rnet сокет домена: сервер не отвечает и клиент не может подключиться к localhost - PullRequest
0 голосов
/ 20 июня 2020

Я новичок в доменных сокетах Unix. Я пытаюсь написать простое клиент-серверное приложение. Сервер будет работать в фоновом режиме и печатать сообщение о том, что он получил соединение с хостом и именем службы, на котором существует клиент. Имя хоста моего клиента зависит от ввода пользователя, поэтому я сделал введенное пользователем имя хоста «localhost». Однако, когда я пытаюсь это сделать, моя клиентская программа не может найти подходящий адрес для подключения к сокету. Кроме того, единственный способ, которым я могу успешно заставить моего клиента присоединиться к сокету по адресу, - это оставить мое имя хоста пустым - и хотя это успешно подключает сокет к адресу, мой сервер не печатает никаких сообщений о том, что он получил соединение от клиента, который существует на хосте x и имени службы y. В соответствии с моим пониманием страницы руководства для getaddrinfo (), оставляя имя хоста пустым, но не устанавливая hints.ai_flags на AI_PASSIVE, просто устанавливает имя хоста в качестве адреса обратной связи. Таким образом, похоже, что мой сервер не отправляет обратно сообщение об успешном подключении, поскольку мой клиент отправляет самому себе свое собственное сообщение («Попытка подключения успешна»). Почему я не могу создать сокет на имени хоста localhost? Мой код для сервера и клиента такой:

#include <netdb.h>
#define BACKLOG 20
#include "server.h"
#include "stddef.h"
#include <string.h>
#include <stdio.h>



int main(){
    int cfd,afd;
    char service[NI_MAXSERV];
    char host[NI_MAXHOST];
    struct addrinfo hints;
    struct addrinfo *result, *rp;
    struct sockaddr_storage claddr;
    char addrstr[NI_MAXHOST+NI_MAXSERV+10];
    memset(&hints,0,sizeof(struct addrinfo));
    socklen_t socklen;
    hints.ai_family=AF_UNSPEC; 
    hints.ai_socktype=SOCK_STREAM;
    hints.ai_next=NULL;
    hints.ai_canonname=NULL;
    hints.ai_addr=NULL;
    hints.ai_flags=AI_PASSIVE | AI_NUMERICSERV;
    if ((getaddrinfo(NULL,PORT_NUM,&hints,&result))!=0){
        perror("Failed to get result pointer of address structs");
    }
    for (rp=result;rp=rp->ai_next;rp!=NULL){
        cfd=socket(rp->ai_family,rp->ai_socktype, rp->ai_protocol);
        if (cfd==-1){
            continue;
        }
        if (bind(cfd,rp->ai_addr, rp->ai_addrlen)==0){
            break;
        }

        close(cfd);
    } 
    if (rp==NULL){

        perror("Reached end of address list without finding suitable socket address space");
    }
    freeaddrinfo(result);
    listen(cfd,BACKLOG);
    for (;;){
        socklen=sizeof(struct sockaddr);
        afd=accept(cfd,(struct sockaddr*) &claddr,&socklen);
        if (afd==-1){
            perror("Accept failed");
        }
        getnameinfo((struct sockaddr*) &claddr,socklen,
            host,NI_MAXHOST,service,NI_MAXSERV,0);
        snprintf(addrstr,NI_MAXSERV+NI_MAXHOST+10, "(%s, %s)", host,service);   
        printf("Connection received from %s", addrstr);

    }

}

и клиент:

#include <netdb.h>
#include "server.h"
#include "stddef.h"
#include <stdio.h>

int main(int argc, char*argv[]){
    struct addrinfo hints;
    struct addrinfo *result, *rp;
    int cfd;
    socklen_t socklen;
    hints.ai_family=AF_UNSPEC; //can accept IPV4 or IPV6
    hints.ai_socktype=SOCK_STREAM;
    hints.ai_next=NULL; 
    hints.ai_canonname=NULL;
    hints.ai_addr=NULL;
    hints.ai_flags=AI_NUMERICSERV; 
    if ((getaddrinfo(argv[1],PORT_NUM,&hints,&result))!=0){
        perror("getaddrinfo failed");
    }
    for (rp=result;rp=rp->ai_next;rp!=NULL){
        cfd=socket(rp->ai_family,rp->ai_socktype, rp->ai_protocol);
        if (cfd==-1){
            continue;
        }
        if (connect(cfd,rp->ai_addr,rp->ai_addrlen)!=-1){
            printf("Connection attempt successful");
            break;
        }
        close(cfd);
    }
    if (rp==NULL){
        perror("Could not connect socket to any address");
    }
    freeaddrinfo(result);

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...