完成端口怎么得到客户端IP地址?

ringphone 2005-06-29 04:51:09
是用GetAcceptExSockaddrs吗?

但是这样有个问题,就是看关于完成端口的资料,有这么一段:

未获取函数指针就调用函数(如直接连接mswsock..lib并直接调用AcceptEx)的消耗是很大的,因为AcceptEx 实际上是存在于Winsock2结构体系之外的。每次应用程序常试在服务提供层上(mswsock之上)调用AcceptEx时,都要先通过WSAIoctl获取该函数指针。如果要避免这个很影响性能的操作,应用程序最好是直接从服务提供层通过WSAIoctl先获取这些APIs的指针。

根据这个建议,于是用WSAIoctl获取函数指针:

#include <mswsock.h>
GUID acceptex_guid = WSAID_ACCEPTEX;
LPFN_ACCEPTEX g_fnAcceptEx;
LPFN_GETACCEPTEXSOCKADDRS g_fnGetAcceptExSockaddrs;
DWORD bytes;

SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

WSAIoctl(sock,SIO_GET_EXTENSION_FUNCTION_POINTER,&acceptex_guid,sizeof(acceptex_guid),&g_fnAcceptEx,sizeof(g_fnAcceptEx),&bytes,NULL,NULL);

WSAIoctl(sock,SIO_GET_EXTENSION_FUNCTION_POINTER,
&acceptex_guid,
sizeof(acceptex_guid),
&g_fnGetAcceptExSockaddrs,
sizeof(g_fnGetAcceptExSockaddrs),
&bytes,
NULL,
NULL
);

然后用g_fnAcceptEx和g_fnGetAcceptExSockaddrs代替AcceptEx和GetAcceptExSockaddrs,
g_fnAcceptEx正常,但是客户端连接后用g_fnGetAcceptExSockaddrs却得不到客户端IP地址,
而直接用AcceptEx和GetAcceptExSockaddrs却能得到,真是奇怪了。而且GetAcceptExSockaddrs
必须是用AcceptEx而不是g_fnAcceptEx接受的客户端才能得到地址。
难道说不能通过获取API的指针来调用吗?
...全文
639 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
ringphone 2005-06-30
  • 打赏
  • 举报
回复
To ddgfei(不懂规矩):
我没有做客户端,是用ftp命令测试,VC调试服务器程序的。

To DentistryDoctor(雅克医生<改行做程序员了>) :
你的方法对完成端口SOCKET不起作用,getpeername失败,WSAGetLastError返回代码10057,Error LookUp翻译过来意思是:

由于套接字没有连接并且 (当使用一个 sendto 调用发送数据报套接字时) 没有提供地址,发送或接收数据的请求没有被接受。

但是我在WSAGetLastError后紧接着调用send是成功的,这个错误看起来蛮奇怪的。看来是必须用GetAcceptExSockaddrs才行。
ddgfei 2005-06-30
  • 打赏
  • 举报
回复
楼主你在客户端也是调用SIO_GET_EXTENSION_FUNCTION_POINTER这个函数么?
如果在一台机子上同时调用,客户端会失败,你可以试一试。以前我做地时候遇到这样得情况
http://community.csdn.net/Expert/topic/3953/3953924.xml?temp=.3521845
ddgfei 2005-06-30
  • 打赏
  • 举报
回复
以前遇到过,Windows网络编程中得吧?
ringphone 2005-06-30
  • 打赏
  • 举报
回复
搞错掉了,看了头文件才知道,g_fnGetAcceptExSockaddrs需要传WSAID_GETACCEPTEXSOCKADDRS参数,
即:
GUID GetAcceptExaddrsGuid = WSAID_GETACCEPTEXSOCKADDRS;
WSAIoctl(sock,SIO_GET_EXTENSION_FUNCTION_POINTER,
&GetAcceptExaddrsGuid,
sizeof(GetAcceptExaddrsGuid),
&g_fnGetAcceptExSockaddrs,
sizeof(g_fnGetAcceptExSockaddrs),
&bytes,
NULL,
NULL
);
才对,原来代码中g_fnGetAcceptExSockaddrs其实得到的是AcceptEx指针,偏偏两个函数参数是一样多且类型可兼容,真是上一大当。
问题解决,只能散分了,下班前结贴,跟帖有分。
Zhymax 2005-06-30
  • 打赏
  • 举报
回复
学习
DentistryDoctor 2005-06-30
  • 打赏
  • 举报
回复
SOCKADDR_IN remote_addr;
int remote_addr_len = sizeof(remote_addr);
if(SOCKET_ERROR==getpeername(m_hSocket,(SOCKADDR*)&remote_addr,&remote_addr_len))
{
}
else
{
m_nRemoteIP = remote_addr.sin_addr.s_addr;
m_nRemotePort= DWORD(ntohs(remote_addr.sin_port));
}

SOCKADDR_IN local_addr;
int local_addr_len = sizeof(local_addr);
if(SOCKET_ERROR==getsockname(m_hSocket,(SOCKADDR*)&local_addr,&local_addr_len))
{
}
else
{
m_nLocalIP = local_addr.sin_addr.s_addr;
m_nLocalPort= DWORD(ntohs(local_addr.sin_port));
}
ringphone 2005-06-30
  • 打赏
  • 举报
回复
没有人这么做过吗?
ddgfei 2005-06-30
  • 打赏
  • 举报
回复
所以必须使用GetAcceptExSockaddrs来获得端口得地址
ddgfei 2005-06-30
  • 打赏
  • 举报
回复
可能是因为你使用<mswsock.h>
这个头文件得缘故
helldream2002 2005-06-30
  • 打赏
  • 举报
回复
softrain 2005-06-30
  • 打赏
  • 举报
回复
获取客户端地址有那么麻烦吗?getpeername不就是获取SOCKET对端的IP地址吗?
goodboyws 2005-06-30
  • 打赏
  • 举报
回复
关注 vs 学习
VCSQLVB 2005-06-30
  • 打赏
  • 举报
回复
最后一个
lifengice0706 2005-06-30
  • 打赏
  • 举报
回复
来晚了,up

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧