1. ホーム
  2. c

[解決済み] Connect: ソケット以外でのソケット操作

2022-01-20 17:49:30

質問

Unixネットワークプログラミングの初心者なのですが、Googleのサーバーに接続するプログラムを書いてみました。しかし、connect()関数を使用しているときにエラーが発生しました。(OS: OS X)

接続エラーです。非ソケットでのソケット操作

4時間ほどやってみたのですが、問題が見つかりませんでした。以下は私のコードです。

#define SERVPORT 80

int main (int argc, char **argv)
{
  int i, sockfd;
  struct hostent *host;
  struct sockaddr_in serv_addr;

  if ( (host = gethostbyname(argv[1])) == NULL) {
    printf("gethostbyname error\n");
    exit(1);
  }

  for (i = 0; host->h_addr_list[i]; i++) {
    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0) == -1)) {
    printf("socket error\n");
    exit(1);
    }

    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(SERVPORT);
    serv_addr.sin_addr = *( (struct in_addr *)host->h_addr_list[i]);
    const char *ip = inet_ntoa(serv_addr.sin_addr);
    printf("connect to %s\n", ip);

    if (connect(sockfd, (struct sockaddr *) &serv_addr,
            sizeof(struct sockaddr)) == -1) {
      printf("connect error:%s\n", strerror(errno));
      exit(1);
    }

 }
  return 0;
}

解決するには?

問題がわかりました。 それはこの行です。

if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0) == -1))

演算子は==演算子より優先されます。 socket(...) == -1 という真偽値を代入された結果、sockfd は "0" に初期化されています。

ソケットの初期化をこのように変更します。

  for (i = 0; host->h_addr_list[i]; i++) 
  {

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1)
    {
        printf("socket error\n");
        exit(1);
    }

あるいは、同じ行に「代入して比較する」というやり方がお好みなら、こう言うこともできるかもしれません。

if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

微妙な違いに注目してください。