Вызов socket :: connect, socket :: bind, socket :: listen без использования функции getaddrinfo () перед этим

Во всем примере, включая Руководство Биджа, IP-адрес предоставляется в точечной нотации, а затем подается на ::getaddrinfo(), Эта почта не отвечает на мой вопрос.

После чего addrinfo struct используется для функций, связанных с сокетами (например, connect(), bind(), listen()). Например:

struct addrinfo hints, *res;
// ... create socket etc.
connect(sockfd, res->ai_addr, res->ai_addrlen);

пример
Переменная ai_addr имеет тип sockaddr который может быть безопасно типизированный до sockaddr_storage, sockaddr_in а также sockaddr_in6,

Вопрос:

Если я приведу sockaddr в sockaddr_in (или же sockaddr_in6)

sockaddr_in& ipv4 = (sockaddr_in&)(sockaddr_variable);

и кормить ниже информации:

  • ipv4.sin_family = AF_INET
  • ipv4.sin_addr = [IP-адрес в порядке байтов нетто]
  • ipv4.sin_port = [Номер порта в порядке байтов нетто]

Могу ли я позвонить connect() метод, непосредственно использующий вышеупомянутую информацию?

connect(sockfd, &ipv4, sizeof(ipv4));

С моей программой это не работает. Я что-то упустил или есть лучший способ?

Мотивация заключается в том, что если у нас есть информация об IP-адресе, порте и т. Д. В формате, удобном для чтения через сокет, то зачем проходить цикл getaddrinfo()

0

Решение

Убедитесь, что вы размещаете свои значения в сетевом порядке, вот небольшой пример:

#include<stdio.h>
#include<sys/socket.h>
#include<arpa/inet.h>

int main(int argc, char *argv[])
{
int sock;
struct sockaddr_in server;

sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1)
{
printf("Could not create socket\n");
}
printf("Socket created\n");

server.sin_family = AF_INET;
// 173.194.32.207 is a google address
server.sin_addr.s_addr = 173 | 194 << 8 | 32 << 16 | 207 << 24;
server.sin_port = 0x5000; // port 80

if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0)
{
perror("connect failed. Error");
return 1;
}

printf("Connected\n");

close(sock);
return 0;
}
2

Другие решения

Сначала проверьте, доступна ли машина & серверное приложение работает на компьютере с помощью утилиты netstat. Используйте метод inet_aton для преобразования точечного адреса в сетевой порядок байтов. Наконец, запишите значение ошибки, возвращенное соединением, чтобы получить точную причину сбоя.

0

Стоит отметить, что призыв socket::{connect, bind, ...} это неправильно: это C APIs и C не имеют пространств имен, классов и так далее.

Вы должны использовать getaddrinfo так как это намного проще и безопаснее в использовании. Но ничто не мешает вам использовать struct sockaddr и все его варианты. В самом деле, getaddrinfo является своего рода оберткой, как указано в man(3) getaddrinfo:

Функция getaddrinfo () объединяет функциональность
предоставляемые функциями gethostbyname (3) и getservbyname (3) в
единый интерфейс, но в отличие от последних функций, getaddrinfo ()
повторно вводить и позволяет программам устранить зависимость IPv4-IPv6
Cies.

Пример:

#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main()
{
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_port   = htons(80);

inet_pton(addr.sin_family, "198.252.206.16", &addr.sin_addr);

int fd = socket(addr.sin_family, SOCK_STREAM, 0);

if (fd == -1)
; /* could not create socket */

if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
;  /* could not connect */

close(fd);

}
0
По вопросам рекламы [email protected]