首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Winsock的connect()永久返回WSAETIMEDOUT,但PuTTY在同一端口上连接

Winsock的connect()永久返回WSAETIMEDOUT,但PuTTY在同一端口上连接
EN

Stack Overflow用户
提问于 2010-07-28 08:10:48
回答 5查看 2.7K关注 0票数 4

可能是我到目前为止遇到的最奇怪的bug。

我需要连接到在Windows XP Embedded下运行的某些第三方应用程序。网络连接存在并且工作正常:我可以使用在Windows XP SP3上运行的PuTTY连接到预期的端口,并执行一些类似远程登录的操作。现在,我的应用程序是一个非常简单的C (VC++ 2008)程序:

代码语言:javascript
运行
复制
int _tmain(int argc, _TCHAR* argv[])
{
    WSADATA wsaData = { 0 };
    if (SOCKET_ERROR == WSAStartup(MAKEWORD(2, 0), &wsaData))
        return Error("Failed to initialize sockets.");

    SOCKET client = INVALID_SOCKET;

    const char *pserver = "172.22.1.3";

    client = socket(AF_INET, SOCK_STREAM, 0);

    if (INVALID_SOCKET != client)
    {
        sockaddr_in s = { 0 };
        s.sin_family = AF_INET;
        s.sin_port = htons(4799);
        hostent *e = gethostbyname(pserver);
        memmove(&s.sin_addr, e->h_addr, e->h_length);

        std::cout << "Connecting to: " << pserver << std::endl;

        if (SOCKET_ERROR != connect(client, (sockaddr*)&s, sizeof(s)))
        {
            std::cout << "Successfully connected." << std::endl;
        }
        else
            std::cout << "Can't connect: " << WSAGetLastError() << std::endl;
    }

    getchar();

    if (INVALID_SOCKET != client)
        closesocket(client);

    return 0;
}

每次我编译和运行这个程序时,我都会收到WSAETIMEDOUT错误。不知所措,我开始深入挖掘,在接收器端产生了两个Wireshark转储文件-一个使用PuTTY,另一个使用我的应用程序,从同一台PC上运行,并连接到相同的设备(下面是第一个同步数据包)。

PuTTY:

代码语言:javascript
运行
复制
No.     Time        Source                Destination           Protocol Info
      1 0.000000    172.22.1.61           172.22.1.3            TCP      atc-lm > 4799 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=0 TSV=0 TSER=0

Frame 1 (78 bytes on wire, 78 bytes captured)
Ethernet II, Src: Dell_b8:4a:31 (00:26:b9:b8:4a:31), Dst: EEPD_96:04:48 (00:e0:33:96:04:48)
Internet Protocol, Src: 172.22.1.61 (172.22.1.61), Dst: 172.22.1.3 (172.22.1.3)
Transmission Control Protocol, Src Port: atc-lm (1170), Dst Port: 4799 (4799), Seq: 0, Len: 0

0000  00 e0 33 96 04 48 00 26 b9 b8 4a 31 08 00 45 00   ..3..H.&..J1..E.
0010  00 40 04 a1 40 00 80 06 9b aa ac 16 01 3d ac 16   .@..@........=..
0020  01 03 04 92 12 bf 9a 99 fc ec 00 00 00 00 b0 02   ................
0030  ff ff 2c bd 00 00 02 04 05 b4 01 03 03 00 01 01   ..,.............
0040  08 0a 00 00 00 00 00 00 00 00 01 01 04 02         ..............

我的应用程序:

代码语言:javascript
运行
复制
No.     Time        Source                Destination           Protocol Info
      1 0.000000    Dell_b8:4a:31         EEPD_96:04:48         FC       [Malformed Packet]

Frame 1 (78 bytes on wire, 78 bytes captured)
Ethernet II, Src: Dell_b8:4a:31 (00:26:b9:b8:4a:31), Dst: EEPD_96:04:48 (00:e0:33:96:04:48)
MDS Header(Unknown(0)/Unknown(0))
[Malformed Packet: FC]

0000  00 e0 33 96 04 48 00 26 b9 b8 4a 31 00 00 00 00   ..3..H.&..J1....
0010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0020  00 00 00 00 00 00 00 00 6d 8b 00 00 00 00 b0 02   ........m.......
0030  ff ff 90 73 00 00 02 04 05 b4 01 03 03 00 01 01   ...s............
0040  08 0a 00 00 00 00 00 00 00 00 01 01 04 02         ..............

基本上,整个IP有效负载是用0x00而不是有效字节擦除的。

现在最奇怪的部分来了。我为.NET 3.5写了一个类似的程序:

代码语言:javascript
运行
复制
static void Main(string[] args)
{
    var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Unspecified);
    socket.Connect("172.22.1.3", 4799);

    Console.WriteLine("Connected");

    Console.ReadLine();
    socket.Disconnect(true);
}

相同的Windows XP SP3 PC,相同的网络连接-我的.NET应用程序只需连接到远程应用程序!此外,我原来的C应用程序在另一台运行Windows7 x64的笔记本电脑上运行得很好。经过一天的捆绑,我有两台Windows XP SP3笔记本电脑,我的C应用程序无法连接到远程客户端,还有一台Windows XP SP3和一台Windows 7 x64笔记本电脑,我的C应用程序可以正常运行。

我的第一个猜测是网络驱动程序,但PuTTY和.NET应用程序只能在同一台笔记本电脑上运行!

有没有人尝试过类似的东西,并能给我一些建议?

谢谢。

EN

回答 5

Stack Overflow用户

发布于 2010-08-06 10:03:25

这在我看来不太对劲:

代码语言:javascript
运行
复制
memmove(&s.sin_addr, e->h_addr, e->h_length);
                     ^^^^^^^^^-- here

不能访问VC文档,但它不应该是&e->h_addr吗?

由于您的版本的IP块已清零,因此memmove从错误的位置读取并复制未使用但已清零的内存块是合理的。

票数 1
EN

Stack Overflow用户

发布于 2010-07-28 08:34:50

由于您正在连接到一个IP地址,所以不要使用gethostbyname() (特别是因为您没有检查它是否有错误回复)。请改用inet_addr():

代码语言:javascript
运行
复制
sockaddr_in s = { 0 }; 
s.sin_family = AF_INET; 
s.sin_port = htons(4799); 
s.sin_addr.s_addr = inet_addr(pserver); // <-- here
票数 0
EN

Stack Overflow用户

发布于 2010-08-03 06:58:12

我遇到了一些类似的问题;它返回给我的不是WSAETIMEDOUT,而是WSAEADDRINUSE。setsockopt()解决了这个问题。

我还建议您使用socket(...,IPPROTO_TCP)更新socket(...,0)调用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3348972

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档