2013-02-15 2 views
-2

문제가 해결되었습니다. 근본 원인은 getpeername()의 sockaddr *로 C++ 임시 객체를 전달했기 때문에 getpeername()이 반환 된 후 자동으로 삭제되었습니다.왜 getpeername()이 정상적으로 돌아 오지만 예상대로 결과가 나오지 않습니까?

따라서 net 결과는 0으로 채워집니다.

내 부주의로 불편을 끼쳐 드려 죄송합니다. 이 게시물을 닫으 려구요. 투표를 닫으십시오. 전화가 getpeername는 확인을 반환하는 역할을하지만


#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(); 
} 

코드는, 반환 된 데이터는 잘못된 (0 가득)이며, VC 그러나 ++ 2012로 컴파일, 왜?

+0

OT : 영업의 소스 코드 조각에서 주석으로 표현 된 다음과 같이

은 당신이 할 수있는, 주소와 포트를 인쇄하려면 왜 그냥 2 차 및 3 차 매개 변수를 사용하지를'동의()'를 사용하여 피어를 얻으시겠습니까? – alk

+0

이것은 주요 문제에 초점을 맞추기 위해 매우 단순화 된 코드입니다. 내 진짜 목적은 accept() 후에 오랫동안 소켓에 의해 피어 정보를 얻는 것이다. – xmllmx

+1

'sockaddr_in client_addr {};'에서 빈 빈 대괄호의 목적은 무엇입니까? 이것도 컴파일됩니까? '= '가 없기 때문에 초기화가 아닙니다. – unwind

답변

2

getpeername()sockaddr_<something> 구조체를 초기화한다. <something>in과 같으면 이진 형식의 IP 주소와 포트를 보유합니다.

그렇습니다. 이 아닙니다.은 피어의 이름/주소 및 포트의 ASCII 표현을 보유하고있는 문자 버퍼를 가지고 있습니다.

또한 sockaddr_in의 값은 네트워크 바이트 순서로 유지됩니다.

#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)); 
관련 문제