Accept后用GetSockName函数为什么不能得到接收连接端的端口地址,而是得到了监听端口地址

时间:2022-10-16 11:03:51
我的代码如下:(其中CListenSocket和CCommuSocket都是派生自CSocket,分别是监听套接字和连接套接字)
void CListenSocket::OnAccept(int nErrorCode) 
{
  CCommuSocket* pCommuSock = new CCommuSocket();

  if (Accept(*pCommuSock))
  {
     SOCKADDR_IN  SockAddr;
     int  nAddrlen = sizeof(SOCKADDR_IN);
     pCommuSock->GetSockName((SOCKADDR*)&SockAddr, &nAddrlen);
     ....
  }
  .....
}
为什么我在GetSockName语句处设置断点,发现得到的SockAddr是服务器监听端口地址,而非接收连接端的端口地址。望请赐教

4 个解决方案

#1


我的一个建议,在我的使用中从 CSocket 派生出来的类,有时不能接收到网络消息,如连接,断连,后来我改用 CAsyncSocket 派生出来,就解决了。

您也可以看看是否是这样的原因。

要获取连接方的 IP  我是按下面写的(原创)注: public CAsyncSocket

void CSeverSocket::OnAccept(int nErrorCode) 
{
CClientSocket* pClient;
pClient = new CClientSocket;
int nLength;
SOCKADDR_IN sockAddr;
IN_ADDR     ipConnect;
nLength = sizeof(SOCKADDR_IN);


//同时获取对方的IP地址
if( Accept(*pClient,(SOCKADDR*)&sockAddr,&nLength) )
{
ipConnect = sockAddr.sin_addr;
sprintf( pClient->m_szClientAddr,"%d.%d.%d.%d",
    ipConnect.S_un.S_un_b.s_b1,
ipConnect.S_un.S_un_b.s_b2,
ipConnect.S_un.S_un_b.s_b3,
ipConnect.S_un.S_un_b.s_b4);

                  //自定义,根据地址获取主机名
GetHostNameByAddr(pClient->m_szClientName,pClient->m_szClientAddr);

// 在列表中添加SeverSocket指针
// 在Client中完成断开连接时 m_ClientList 中成员的清除工作
pClient->m_pParent = (CSeverSocket*)this;

// 保存自已的爸爸到儿子的记忆中
// 儿子有数据处理时直接找到爷爷处理
pClient->m_pGrandpa = m_pParent ;

pClient->CreateCanSendEvent();
m_ClientList.Add(pClient);

TRACE0("已响应用户请求,在列表中的加入指针记录\n");
}
else
delete pClient;

PostStateMsg();
CAsyncSocket::OnAccept(nErrorCode);
}

#2


谢谢回答,不过问题不在这里,问题是我为什么使用GetSockName得不到连接套接字端口地址,而是得到了监听端口地址。(我的client与server在同一机器上)。

#3


怎么会这样。
GetSockName这个函数用来接收本地接口的地址信息,
而且在调用该函数时必须用Accept返回的套接字调用。
返回的决对是本地连接套接字的地址。
但调用之前应保证已与对方取得连接

#4


得到对端的地址用GetPeerName(),
GetSockName()得到的是本端的socket地址。

#1


我的一个建议,在我的使用中从 CSocket 派生出来的类,有时不能接收到网络消息,如连接,断连,后来我改用 CAsyncSocket 派生出来,就解决了。

您也可以看看是否是这样的原因。

要获取连接方的 IP  我是按下面写的(原创)注: public CAsyncSocket

void CSeverSocket::OnAccept(int nErrorCode) 
{
CClientSocket* pClient;
pClient = new CClientSocket;
int nLength;
SOCKADDR_IN sockAddr;
IN_ADDR     ipConnect;
nLength = sizeof(SOCKADDR_IN);


//同时获取对方的IP地址
if( Accept(*pClient,(SOCKADDR*)&sockAddr,&nLength) )
{
ipConnect = sockAddr.sin_addr;
sprintf( pClient->m_szClientAddr,"%d.%d.%d.%d",
    ipConnect.S_un.S_un_b.s_b1,
ipConnect.S_un.S_un_b.s_b2,
ipConnect.S_un.S_un_b.s_b3,
ipConnect.S_un.S_un_b.s_b4);

                  //自定义,根据地址获取主机名
GetHostNameByAddr(pClient->m_szClientName,pClient->m_szClientAddr);

// 在列表中添加SeverSocket指针
// 在Client中完成断开连接时 m_ClientList 中成员的清除工作
pClient->m_pParent = (CSeverSocket*)this;

// 保存自已的爸爸到儿子的记忆中
// 儿子有数据处理时直接找到爷爷处理
pClient->m_pGrandpa = m_pParent ;

pClient->CreateCanSendEvent();
m_ClientList.Add(pClient);

TRACE0("已响应用户请求,在列表中的加入指针记录\n");
}
else
delete pClient;

PostStateMsg();
CAsyncSocket::OnAccept(nErrorCode);
}

#2


谢谢回答,不过问题不在这里,问题是我为什么使用GetSockName得不到连接套接字端口地址,而是得到了监听端口地址。(我的client与server在同一机器上)。

#3


怎么会这样。
GetSockName这个函数用来接收本地接口的地址信息,
而且在调用该函数时必须用Accept返回的套接字调用。
返回的决对是本地连接套接字的地址。
但调用之前应保证已与对方取得连接

#4


得到对端的地址用GetPeerName(),
GetSockName()得到的是本端的socket地址。