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

跨Windows设备WLAN环境下Socket连接失败问题求助

问题解决:跨Windows设备Socket连接失败+ping不通的处理方案

一、先解决设备间ping不通的核心问题

ping不通是网络层的基础故障,必须优先解决:

  • 检查网段一致性:在两台设备的命令行执行ipconfig,确认IPv4地址处于同一子网(比如均为192.168.1.x段)。
  • 关闭或配置防火墙:临时关闭两台设备的Windows Defender防火墙,或者在防火墙规则中添加允许ICMP(ping)请求的入站/出站规则。
  • 关闭路由器AP隔离:登录路由器后台,查找并关闭「AP隔离」「无线隔离」类功能(多数家用路由器默认开启该功能,阻止同WiFi下设备互访)。
  • 确认无线连接一致性:两台设备需连接到同一WiFi热点的同一频段(避免一台连2.4G、一台连5G,部分路由器会隔离不同频段设备)。

二、Socket代码优化调整

即使ping通,原代码仍存在适配跨设备连接的问题,以下是修改方案:

服务端代码修改点

  1. 将绑定的固定IP改为INADDR_ANY,监听所有可用网络接口(避免服务端IP变动导致无法访问);
  2. 补充listen失败后的退出逻辑;
  3. 接收消息后添加字符串结束符,避免乱码。

修改后的服务端代码:

#include "stdafx.h"
#include <winsock.h>
#include <WS2tcpip.h>
#include <iostream>

int main(){
    SOCKET serverSocket, acceptSocket;
    int port = 55555;
    WSADATA wsaData;
    int wsaerr;
    WORD wVersionRequested = MAKEWORD(2, 2);
    wsaerr = WSAStartup(wVersionRequested, &wsaData);
    if (wsaerr != 0) {
        std::cout << "找不到Winsock动态链接库!" << std::endl;
        return 0;
    }
    else {
        std::cout << "找到Winsock动态链接库!" << std::endl;
        std::cout << "状态: " << wsaData.szSystemStatus << std::endl;
    }

    serverSocket = INVALID_SOCKET;
    serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (serverSocket == INVALID_SOCKET) {
        std::cout << "socket() 错误: " << WSAGetLastError() << std::endl;
        WSACleanup();
        return 0;
    }
    else {
        std::cout << "socket() 执行成功!" << std::endl;
    }

    sockaddr_in service;
    service.sin_family = AF_INET;
    // 绑定到所有可用网络接口,适配跨设备访问
    service.sin_addr.s_addr = INADDR_ANY;
    service.sin_port = htons(port);
    if (bind(serverSocket, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR) {
        std::cout << "bind() 失败: " << WSAGetLastError() << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 0;
    }
    else {
        std::cout << "bind() 执行成功" << std::endl;
    }


    if (listen(serverSocket, 1) == SOCKET_ERROR) {
        std::cout << "listen(): 监听套接字错误 " << WSAGetLastError() << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 0;
    }
    else {
        std::cout << "listen() 执行成功。等待连接..." << std::endl;
    }

    acceptSocket = accept(serverSocket, NULL, NULL);
    if (acceptSocket == INVALID_SOCKET) {
        std::cout << "accept 失败: " << WSAGetLastError() << std::endl;
        WSACleanup();
        return -1;
    }
    std::cout << "已接受连接" << std::endl;

    char buffer[200];
    int bytecount = recv(acceptSocket, buffer, sizeof(buffer), 0);
    if (bytecount > 0) {
        // 添加字符串结束符,避免乱码
        buffer[bytecount] = '\0';
        std::cout << "收到消息: " << buffer << std::endl;
    }
    else {
        std::cout << "接收消息失败" << std::endl;
        WSACleanup();
    }

    system("pause");
    closesocket(acceptSocket);
    closesocket(serverSocket);
    WSACleanup();

    return 0;
}

客户端代码修改点

  1. 将连接的固定IP替换为服务端设备的实际IPv4地址;
  2. 发送消息时使用字符串实际长度,而非缓冲区总大小;
  3. 补充发送失败时的错误码输出。

修改后的客户端代码:

#include "stdafx.h"
#include <winsock.h>
#include <WS2tcpip.h>
#include <iostream>
#include <cstring> // 用于strlen函数

int main() {
    SOCKET clientSocket;
    int port = 55555;
    WSADATA wsaData;
    int wsaerr;
    WORD wVersionRequested = MAKEWORD(2, 2);
    wsaerr = WSAStartup(wVersionRequested, &wsaData);
    if (wsaerr != 0) {
        std::cout << "找不到Winsock动态链接库!" << std::endl;
        return 0;
    }
    else {
        std::cout << "找到Winsock动态链接库!" << std::endl;
        std::cout << "状态: " << wsaData.szSystemStatus << std::endl;
    }

    clientSocket = INVALID_SOCKET;
    clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (clientSocket == INVALID_SOCKET) {
        std::cout << "socket() 错误: " << WSAGetLastError() << std::endl;
        WSACleanup();
        return 0;
    }
    else {
        std::cout << "socket() 执行成功!" << std::endl;
    }

    sockaddr_in clientservice;
    clientservice.sin_family = AF_INET;
    // 替换为服务端设备的实际IPv4地址(比如192.168.1.100)
    InetPton(AF_INET, _T("192.168.x.x"), &clientservice.sin_addr.s_addr);
    clientservice.sin_port = htons(port);
    if (connect(clientSocket, (SOCKADDR*)&clientservice, sizeof(clientservice)) == SOCKET_ERROR) {
        std::cout << "客户端: connect() 失败: " << WSAGetLastError() << std::endl;
        closesocket(clientSocket);
        WSACleanup();
        return 0;
    }
    else {
        std::cout << "客户端: connect() 执行成功" << std::endl;
        std::cout << "客户端: 可以开始发送和接收数据..." << std::endl;
    }

    char buffer[200];
    std::cout << "请输入消息: ";
    std::cin.getline(buffer, sizeof(buffer));
    // 发送实际输入的字符串长度,避免发送空字符
    int bytecount = send(clientSocket, buffer, strlen(buffer), 0);
    if (bytecount > 0) {
        std::cout << "\n消息已发送" << std::endl;
    }
    else {
        std::cout << "发送消息失败: " << WSAGetLastError() << std::endl;
        WSACleanup();
    }


    system("pause");
    closesocket(clientSocket);
    WSACleanup();
    return 0;
}

三、额外注意事项

  • 编译代码时需链接ws2_32.lib库:在Visual Studio中,通过「项目属性」→「链接器」→「输入」→「附加依赖项」添加该库;
  • 服务端设备需在防火墙中添加入站规则,允许程序或55555端口的TCP连接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 10:25:22