Я новичок в доменных сокетах 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);
}