【问题标题】:Socket is invalid while hooking WSASend/WSARecv on the server在服务器上挂接 WSASend/WSARecv 时套接字无效
【发布时间】:2011-11-14 04:30:08
【问题描述】:

我在 C++ 中使用与挂钩客户端的 WSASend 和 WSARecv 函数相同的方法来挂钩 WSASend 和 WSARecv。在客户端中,我可以从 WSASend/WSARecv 传递的 SOCKET 结构中获取 IP、端口和套接字;但是,对于服务器,当我尝试使用 getpeername 或 getsockname() 时,它们都返回错误 10057 (Socket not connected)...

我相当确定服务器上的钩子是正确的,因为它成功打印了字节,而且我还确定套接字应该是有效的,看看客户端和服务器如何建立成功的连接。

有没有其他方法可以解决这个问题?我一直在互联网上寻找解决方案,但我没有看到任何人遇到同样的问题。

我试过了:

            sockaddr *address = new sockaddr;
            int peer_len;
            getpeername(s, address, &peer_len);
            int err = WSAGetLastError();
            if(err==0)
            {
                char *Str = inet_ntoa(((sockaddr_in*)address)->sin_addr);
                printf("[%s", Str);
                printf(":%d]",ntohs(((sockaddr_in*)address)->sin_port));
            }
            else
            {
                printf("Error %i\n",err);
            }

(同时使用getpeername和getsockname)两者都会导致相同的套接字未连接错误。

我计划使用 C++ dll 获取的数据包并将信息转发到 C# dll,因为这样会更容易管理(无论如何对我来说),但我需要区分每个数据包套接字 ID。

【问题讨论】:

标签: c++


【解决方案1】:

您只能在 已连接的套接字上执行此操作,即从 accept() 调用返回的那个,而不是在侦听的“服务器”套接字上。

【讨论】:

  • 那么在 WSASend/WSARecv 钩子中传递的套接字是监听服务器套接字吗?如果是这样,在读取客户端数据包时,有什么方法可以获取这些客户端的真实套接字ID?
  • 嗯,反过来。 getpeername() 仅在“客户端”套接字上有效 - 您从 accept() 获得的套接字(或在活动端的 connect() 之后)。所有这些都没有考虑到非阻塞套接字。
  • 所以不能直接从服务器获取客户端的IP:PORT:SOCKET id?
  • 如果您的意思是从侦听套接字中获取该信息,则否(除了 accept() 在第二个和第三个参数中返回它)。
猜你喜欢
  • 2014-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-10
  • 2023-03-09
  • 2020-11-04
  • 1970-01-01
  • 2016-06-05
相关资源
最近更新 更多