问题已经解决。根本原因是我传递了一个C ++临时对象作为getpeername()的sockaddr *,它在getpeername()返回后自动销毁。
因此,最终结果为0。
抱歉我粗心大意。我投票结束了这篇文章。也请投票结束。
#include <winsock2.h>
#include <windows.h>
#include <thread>
using namespace std;
void server()
{
sockaddr_in server_addr {};
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(1234);
SOCKET s_listening = socket(AF_INET, SOCK_STREAM, 0);
bind(s_listening, (sockaddr*)&server_addr, sizeof(server_addr));
listen(s_listening, 5);
while (true)
{
auto s_new = accept(s_listening, 0, 0);
sockaddr_in client_addr {};
int size = sizeof(client_addr);
auto ret = getpeername(s_new, (sockaddr*)&client_addr, &size);
//
// ret is 0, which means the call to getpeername is OK.
// But client_addr is full of 0s rather than "127.0.0.1:4". Why?
//
}
}
int main()
{
std::thread(server).detach();
SOCKET s_client = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in client_addr {};
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
client_addr.sin_port = htons(4);
bind(s_client, (sockaddr*)&client_addr, sizeof(client_addr));
sockaddr_in server_addr {};
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(1234);
connect(s_client, (sockaddr*)&server_addr, sizeof(server_addr));
getchar();
}
代码是用VC ++ 2012编译的。但是,虽然函数getpeername的调用返回OK,但返回的数据是错误的(满0),为什么?
答案 0 :(得分:2)
getpeername()
初始化sockaddr_<something>
结构。如果<something>
等于in
,则它将以二进制格式保存ip-address和port。
它不携带一个字符缓冲区,其中包含对等体的名称/地址和端口的任何ASCII表示。
sockaddr_in
中的值也按网络字节顺序保存。
要打印OP的源代码段中的注释所表示的地址和端口,您可以执行以下操作:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
...
int sd = -1; /* init to invalid socket */
... /* get sd a proper value */
sockaddr_in sa = {0}; /* init to all zeros */
socklen_t sl = sizeof(sa);
if (getpeername(sd, (sockaddr *) &sa, &sl))
perror("getpeername() failed");
else
printf("peer is: %s:%hu\n", inetntoa(sa.sinaddr), ntohs(sa.sin_port));