Проблема при компиляции кода подключения сокета в C - PullRequest
7 голосов
/ 30 мая 2011
struct hostent *lh               = gethostbyname(hostname);

int socketDescriptor             = socket(AF_INET,SOCK_STREAM, 0);

sockaddr_in socketInfo;

memset(&socketInfo, 0, sizeof(socketInfo));
socketInfo.sin_family            = AF_INET;
socketInfo.sin_addr.s_addr       = ((in_addr *)(lh->h_addr))->s_addr;
socketInfo.sin_port              = htons(portNumber);

connect(socketDescriptor,&socketInfo,sizeof(socketInfo));

При попытке компилирования я получаю следующую ошибку:

error: cannot convert ‘sockaddr_in*’ to ‘const sockaddr*’ for argument ‘2’ to ‘int connect(int, const sockaddr*, socklen_t)’

Вещи выглядят «по книге», но я что-то упускаю (очевидно).Что это?

Ответы [ 4 ]

12 голосов
/ 30 мая 2011

Я думаю, что вам не хватает struct на sockaddr_in socketInfo.Так что это должно быть struct sockaddr_in socketInfo.

Также было бы неплохо привести socketInfo к struct sockaddr *.

connect(socketDescriptor,&socketInfo,sizeof(socketInfo));

Должно быть

connect(socketDescriptor,(struct sockaddr *) &socketInfo,sizeof(socketInfo));
3 голосов
/ 30 мая 2011
  struct addrinfo *server;
  struct addrinfo hints; 

    memset(&hints, 0, sizeof(struct addrinfo));/*set hints*/
    hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
    hints.ai_socktype = SOCK_STREAM; 
    hints.ai_flags = 0;
    hints.ai_protocol = 0;          /* Any protocol */

 getaddrinfo(srvname,port,&hints,&server); /*get server ip fit args*/

 sid = socket(server->ai_family, server->ai_socktype,server->ai_protocol)
 connect(sid,server->ai_addr, server->ai_addrlen)

Это некоторые кодешипеты, которые будут работать и с которых вы можете начать.

Здесь происходит то, что я создал одну структуру со всеми интеллектуальными данными, а затем объединил ее с некоторой дополнительной информацией, чтобы получитьодин хороший все указатели соответствуют структуре слишком передать, чтобы подключитьсянадеюсь, что это поможет

1 голос
/ 30 мая 2011

Интерфейсы сокетов, помимо того, что они очень старые, преднамеренно нарушаются.Структуры sockaddr_* неявно начинаются с тех же членов sockaddr, поэтому безопасно привести их к базовому типу.struct sockaddr также имеет член sa_family, так что вы также можете решить во время выполнения, используя struct sockaddr*, к какому «производному» (хотя и не на самом деле) типу привести его.сделать, чтобы изменить это приведение struct sockaddr_in* к struct sockaddr*.Обычно это было бы очень обидно.Но не волнуйся;в этом случае все делают это.Я мог бы даже предпочесть привести к void*, потому что в нем меньше символов, и вы получите преобразование имплика в struct sockaddr*.

Однако ... Несколько других не связанных точек:

  1. gethostbyname может дать сбой.На самом деле это происходит довольно часто, например, когда пользователь вводит поддельный адрес.Ваша программа потерпит крах, когда это произойдет.Проверьте, вернул ли он NULL, чтобы избежать этого.

  2. На самом деле, gethostbyname был заменен на getaddrinfo.Используйте это.Это даст вам независимость от протокола, так что вы не будете привязаны к IPv4.Он также возвращает вам struct sockaddr*, так что вам не нужно делать уродливое приведение.

1 голос
/ 30 мая 2011

Если бы это был просто const, он бы работал, но, очевидно, sockaddr и sockaddr_in - это разные типы.

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