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

Windows下Socket错误码sckOpCanceled 1004的成因及编程复现方法

如何复现Socket错误码“The operation was canceled”

该错误对应Windows系统的ERROR_OPERATION_ABORTED(错误码995),核心是本地系统主动终止了Socket的IO操作,并非远程端发送特定“Cancel”信号。以下是几种不同语言的复现方式:

1. C++ (WinSock)

通过Windows API显式取消异步Socket操作:

#include <winsock2.h>
#include <windows.h>
#include <iostream>

#pragma comment(lib, "ws2_32.lib")

int main() {
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    // 创建TCP Socket
    SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    sockaddr_in serverAddr{};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(8080);
    inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr);

    // 开启异步连接通知
    WSAAsyncSelect(sock, GetConsoleWindow(), WM_USER + 1, FD_CONNECT);
    connect(sock, (sockaddr*)&serverAddr, sizeof(serverAddr));

    // 立即取消Socket上的所有异步操作
    CancelIoEx((HANDLE)sock, nullptr);

    // 捕获错误
    MSG msg;
    while (GetMessage(&msg, nullptr, 0, 0)) {
        if (msg.message == WM_USER + 1) {
            int err = WSAGETSELECTERROR(msg.lParam);
            if (err == WSA_OPERATION_ABORTED) {
                std::cout << "复现成功:The operation was canceled" << std::endl;
            }
            break;
        }
    }

    closesocket(sock);
    WSACleanup();
    return 0;
}

原理:调用CancelIoEx主动终止挂起的异步连接操作,触发WSA_OPERATION_ABORTED错误。

2. Python (Windows平台)

借助Windows API取消Socket的IO操作:

import socket
import win32file
import win32api

# 创建非阻塞Socket并发起连接
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setblocking(False)
try:
    s.connect(("127.0.0.1", 8080))
except BlockingIOError:
    pass

# 获取Socket句柄并取消IO操作
handle = win32file._get_osfhandle(s.fileno())
win32api.CancelIoEx(handle, None)

# 触发错误
try:
    s.recv(1024)
except OSError as e:
    if e.winerror == 995:
        print("复现成功:The operation was canceled")
finally:
    s.close()

原理:取消挂起的连接操作后,执行读操作会抛出错误码995的异常,对应目标错误描述。

3. VB6 (贴合旧项目环境)

直接在VB6中调用Windows API取消Winsock操作:

Private Declare Function CancelIoEx Lib "kernel32.dll" (ByVal hFile As Long, ByVal lpOverlapped As Long) As Long
Private Declare Function _get_osfhandle Lib "msvcrt.dll" (ByVal fd As Long) As Long
Private sock As Winsock

Private Sub Form_Load()
    sock.RemoteHost = "127.0.0.1"
    sock.RemotePort = 8080
    sock.Connect
    ' 获取Socket句柄并取消操作
    Dim handle As Long
    handle = _get_osfhandle(sock.SocketHandle)
    CancelIoEx handle, 0
End Sub

Private Sub sock_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
    If Number = 10004 Then ' VB6中WSA_OPERATION_ABORTED对应错误码10004
        MsgBox "复现成功:" & Description ' Description即为"The operation was canceled"
    End If
End Sub

原理:取消Winsock控件的异步连接操作,触发Error事件并输出目标错误描述。

注意事项

  • 所有示例需确保目标端口(如8080)未被监听,让Socket操作处于挂起状态,才能触发取消错误。
  • 该错误的常见触发场景包括:线程终止、显式调用取消IO的API、进程退出前清理挂起操作等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 05:55:18