连接:非套接字上的套接字操作

8

我刚接触Unix网络编程,尝试编写一个连接到Google服务器的程序。但是,在使用connect()函数时出现了错误。(操作系统: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;
}

connectsocklen_t 值应该是 sizeof(struct sockaddr_in) - Brett Hale
你在if语句内部破坏了赋值。调试器将在大约45秒钟内向您显示此问题。修复括号或更好的方法是将赋值移出“if”语句。 - n. m.
1个回答

29

我明白了问题所在。就在这行代码:

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

等号运算符的优先级高于赋值运算符。请仔细查看您在表达式中括号的结构,就会明白我的意思。由于被分配一个布尔表达式(socket(...) == -1),sockfd被初始化为“0”。

将socket初始化更改为:

  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)

注意微妙的差异。


2
如果你正在使用gcc,这是打开-Wall的又一个理由,它会给你“警告:建议在赋值用作真值时加上括号”。 - Jonathon Reinhart
2
你不觉得现在是时候你应该将运算符优先级牢记于心了吗? - user207421
1
@EJP - 我在工作时会把运算符优先级表格的副本藏在我的袖子里的一个3x5卡片上。同一张卡片的另一面是“ls”命令行参数和“HelloWorld.c”清单。我总是忘记 main 函数的第一个参数是 argc 还是 argv。 :) - selbie
1
@JonathonReinhart,感谢您提醒我在重返C语言30年后插入-Wall。它在我发现之前找到了更多的问题。 - Sinc
2
@selbie 我经常手边放着我的K&R(第一版)。优先级表在第49页。:) 完全使用括号最安全,并使vi“%”工作良好,特别是d%用于删除表达式的项。 - Sinc
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接