【问题标题】:Bind() returns -1 in my machine while in others run properlyBind() 在我的机器上返回 -1 而在其他机器上正常运行
【发布时间】:2014-11-15 17:43:31
【问题描述】:

我正在使用 Linux Mint,并且正在尝试开发一个服务器端应用程序,该应用程序将侦听特定端口。我尝试将端口设置为使用htons(0),但仍然是同样的问题。

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>
#include <math.h>

float calculator(char *calculation);

extern int errno;

int main(int argc,char **argv)
{
  int clientaddrlen, listenfd, connectfd, bytes_rcvd, listen_queue_size=1;
  short int port_no;
  char readBuff[1000];
  struct sockaddr_in servaddr, clientaddr;
  pid_t  childpid;
  int status;
  char sendBuff[1025];

  if(argc!=3){
    printf("Usage Format: ./server -p <PortNumber>\n");
    printf("Sample Run: ./server -p 2000\n");
    exit(1);
  }
  port_no = atoi(argv[argc-1]);
  printf("Server running at port #%d\n", port_no);

  // Create server socket.
  if ( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
    fprintf(stderr, "Cannot create server socket! errno %i: %s\n",errno,strerror(errno));
    exit(1);
  }

  printf("Server socket created\n");
  // Bind (attach) this process to the server socket.
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  servaddr.sin_port = htons(port_no);
  errno = bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
  if(errno < 0){
    printf("Server bind failure errno %i: %s\n",errno,strerror(errno));
    exit(1);
  }

鉴于我的代码在其他机器上运行,我想我的系统有问题。我得到的错误是

Server bind failure errno -1: Unknown error -1

这是在绑定系统调用之后,由于某种原因在我的系统中返回 -1。我的系统中是否存在导致此问题的问题?

【问题讨论】:

  • 您尝试使用哪个端口号?为什么在调用bind() 之后不删除显然不相关的几十行?
  • @BillLynch 编辑了我的答案,我尝试了不同的端口号和 htons(0),但它仍然崩溃
  • 显着改变您的问题并不是一个好主意。因此,一些评论和/或答案可能变得难以理解!
  • OT: short int port_no; 不会正确存储值 &gt; 0x7ff。请改用unsigned short int(或只是int)。

标签: c sockets linux-mint


【解决方案1】:

bind() 在内部设置errno 以防发生故障。不要覆盖它。

来自man bind

返回值

成功时返回零。出错时,返回 -1,并正确设置 errno。

所以这个

  errno = bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
  if(errno < 0){
    printf("Server bind failure errno %i: %s\n",errno,strerror(errno));
    exit(1);
  }

应该看起来像:

  int result = bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
  if(result < 0) {
    fprintf(stderr, "Server bind failure errno %i: %s\n", errno, strerror(errno));
    exit(EXIT_FAILURE);
  }

甚至更好:

  int result = bind(listenfd, (struct sockaddr *) &servaddr, sizeof servaddr);
  if(result < 0) {
    perror("Server - bind() failed");
    exit(EXIT_FAILURE);
  }

注意:错误消息应转到标准错误输出。

【讨论】:

  • 我不知道 errno 是在内部设置的。用新信息和新错误号编辑了我的代码
  • @JohnDemetriou:我回滚了您的代码更新。如果更新您的问题,请保持原问题不变。
  • 这有点令人困惑,您指出我的代码中有一个错误,但问题是由于使用了错误的端口号,我们如何解决这个问题? :P
  • @JohnDemetriou:只需添加更正的代码作为对您问题的补充。但是,请保留原始代码。
  • 哦,好的。我会这样做。我相信你是对的
【解决方案2】:

我用errorno错了。它是在bind() 函数内部设置的,我需要设置一个不同的变量来存储bind() 的返回值。

所以在将我的代码更改为:

 int result = bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));

  if(result < 0)
    {
      printf("Server bind failure errno %i: %s\n",errno,strerror(errno));
      exit(-1);
    }

我找到了真正的errno,它是 13 岁。

Errorno 13 代表Permission denied

事实证明,1080 下的系统端口是为 root 保留的,这就是我收到错误的原因。而在其他系统中,它必须超过 1024。我不知道为什么 htons(0) 会出错,但是当我将端口更改为 2000 而不是 1025 时,它起作用了。为了使用 1080 以下的端口,我必须使用 sudo 运行应用程序。

【讨论】:

  • 端口小于或等于 1024(不是 1080)需要特权才能使用。
  • 我不知道为什么,但我尝试了 1025-1079,但它在我的系统上也不起作用
  • @alk 将我的答案添加到你的答案中,这样我就可以接受它,我将删除它。你应得的,因为我因为你发现了错误
  • 我提供了帮助,但您自己找到了根本原因,并由此提供了正确的答案,顺便说一句,您也可以接受。
  • @alk 在我接受自己之前必须经过两天:P 但我不应该用正确的 errorno 代码编辑我的问题,以便将来的问题查看者不会阅读他们软件的错误代码吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-24
  • 1970-01-01
  • 1970-01-01
  • 2019-04-21
  • 1970-01-01
相关资源
最近更新 更多