You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

绑定特权端口失败:getsockopt(SO_ERROR)无法获取错误,errno=13

关于bind失败后getsockopt(SO_ERROR)无法获取错误的问题解答

问题原因

  • SO_ERROR选项是为异步套接字操作设计的(比如非阻塞模式下的connect,或通过select/poll监听的异步事件),用来获取异步操作完成后的错误状态。而bind是同步操作,失败时会直接返回-1并设置errno,内核不会将错误码存入SO_ERROR,所以你调用getsockopt拿到的err值为0是正常行为。
  • 代码里rc = rc | bind(...)的写法存在问题:setsockopt成功返回0,bind失败返回-1,按位或后rc会变成-1,但这种写法会混淆两次调用的结果,应该单独检查bind的返回值。

正确的错误处理方式

对于同步的bind调用,直接通过返回值判断是否失败,失败时读取errno即可。SO_ERROR仅在异步操作场景下才会被内核设置。

修正后的代码示例:

#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <sys/time.h>
#include <errno.h>

int main() {
    int _fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (_fd == -1) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    int on = 1;
    int rc = setsockopt(_fd, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&on), sizeof(on));
    assert(rc == 0);

    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(151); // 特权端口

    rc = bind(_fd, (struct sockaddr*)&server, sizeof(server));
    if (rc == -1) {
        printf("bind failed, errno=%d: %s\n", errno, strerror(errno));
    } else {
        printf("bind success\n");
    }

    // 尝试获取SO_ERROR,此时应为0(无异步错误)
    int err = -1;
    socklen_t len = sizeof(err);
    int rc2 = getsockopt(_fd, SOL_SOCKET, SO_ERROR, &err, &len);
    printf("rc2=%d, SO_ERROR=%d\n", rc2, err);

    close(_fd);
    return 0;
}

补充说明

  • 你遇到的errno=13对应EACCES,是因为绑定特权端口(1-1023)需要进程拥有root权限,解决方法是用root权限运行程序,或修改端口为1024及以上。
  • SO_ERROR的典型使用场景:将socket设置为非阻塞模式后调用connect,此时connect会立即返回-1且errno=EINPROGRESS,之后通过select监听socket可写事件,事件触发后再调用getsockopt(SO_ERROR)获取连接是否成功的错误码。

内容的提问来源于stack exchange,提问作者Arnaud Loonstra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 11:50:23