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

x86_64汇编实现Web服务器:socket/bind/listen调用异常排查

x86_64汇编Web服务器bind操作失败排查

我尝试用x86_64汇编编写Web服务器,尽管传入了正确参数,服务器始终无法完成bind操作。将参数传入自定义函数测试时,所有函数均未返回-1,但尝试连接localhost端口6000时,收到如下错误:

Failed to connect to localhost port 6000 after 0 ms: Couldn't connect to server

相关汇编代码如下:

section .text
    extern socket, bind, listen, accept, perror
    global main

main:
    
    ; allocating sockaddr_in
    sub rsp, SIZE_OF_SERVER_ADDR

    ; ; sin_family
    mov word [rsp], AF_INET

    ; ; sin_port 
    mov word [rsp + 2], PORT

    ; ; s_addr
    mov dword [rsp + 4], INADDR_ANY

    ; ; unsigned char data[8]
    mov qword [rsp + 8], 0x0

    mov rdi, AF_INET
    mov rsi, SOCK_STREAM
    mov rdx, 0
    call socket

    cmp rax, 0
    jl exit_socket_error

    ; holding the socket_fd
    mov r12, rax
    
    mov rdi, r12
    mov rsi, rsp
    mov rdx, SIZE_OF_SERVER_ADDR
    call bind

    cmp rax, 0
    jl exit_bind_error

    mov rdi, r12
    mov rsi, 10
    call listen

    cmp rax, 0
    jl exit_error

    call listening_msg

while:
    mov rdi, r12 
    mov rsi, rsp
    mov rdx, 4
    call accept

    cmp rax, 0
    jl exit_error

    call client_connect

    jmp while

问题排查与修复方案

1. 端口号未转换为网络字节序

TCP/IP协议要求端口号必须使用网络字节序(大端序),但x86_64架构是小端序,直接将PORT赋值给sin_port会导致端口解析错误。需要用htons()函数转换端口号:

section .text
    extern socket, bind, listen, accept, perror, htons ; 添加htons声明
    global main

; ... 其他代码 ...

    ; ; sin_port 
    mov rdi, PORT
    call htons
    mov word [rsp + 2], ax ; 写入转换后的大端序端口

2. 检查SIZE_OF_SERVER_ADDR的定义

struct sockaddr_in在x86_64系统中的标准大小是16字节,确保SIZE_OF_SERVER_ADDR宏被定义为16,否则bind会因地址长度不匹配失败。

3. accept调用参数错误

当前accept的第三个参数传的是4,不符合系统调用要求。需要传入指向struct socklen_t变量的指针,且该变量初始化为地址结构的大小:

while:
    ; 在栈上准备socklen_t变量
    mov dword [rsp - 4], SIZE_OF_SERVER_ADDR
    mov rdi, r12 
    mov rsi, rsp ; 客户端地址缓冲区
    mov rdx, rsp - 4 ; socklen_t变量指针
    call accept

4. 完善错误处理

当前代码在错误分支未打印具体错误信息,建议在exit_bind_error等分支中调用perror输出系统错误:

exit_bind_error:
    mov rdi, "bind failed"
    call perror
    ; 退出程序
    mov rax, 60 ; exit系统调用号
    mov rdi, 1
    syscall

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 12:28:14