tags:

views:

43

answers:

3

I want to get the IP address of the socket that's connected to my server socket. I've included my code.

The sa_data doesn't return char[14] of the type "xxx.xxx.xxx.xxx". Instead, it returns [11][1][xxx][xxx][xxx][xxx][][][][][][][]...[]. Can anyone help?

int InitialResult;
char SendMessage[1024];
char ReceiveMessage[1024];
WSADATA WSAData;
addrinfo Hints;
addrinfo *Result;
SOCKET ListenSocket;
SOCKET ClientSocket;

ZeroMemory(&Hints, sizeof(Hints));
Hints.ai_family = AF_INET;
Hints.ai_socktype = SOCK_STREAM;
Hints.ai_protocol = IPPROTO_TCP;
Hints.ai_flags = AI_PASSIVE;
while(1)
{
    InitialResult = WSAStartup(MAKEWORD(2,2), &WSAData);
    if (InitialResult != 0)
    {
        cout << "WSA start up failed.";
    }
    InitialResult = getaddrinfo(NULL, portnumber, &Hints, &Result);
    if (InitialResult != 0)
    {
        cout << "Get address information failed.";
        WSACleanup();
    }
    ListenSocket = socket(Result->ai_family, Result->ai_socktype, Result->ai_protocol);
    if (ListenSocket == INVALID_SOCKET)
    {
        cout << "Socket initialization failed.";
        WSACleanup();
    }
    InitialResult = bind(ListenSocket, Result->ai_addr, (int)Result->ai_addrlen);
    if (InitialResult == SOCKET_ERROR)
    {
        cout << "Bind failed." << portnumber;
        closesocket(ListenSocket);
        ListenSocket = INVALID_SOCKET;
        WSACleanup();
    }
    InitialResult = listen(ListenSocket, SOMAXCONN);
    if (InitialResult == SOCKET_ERROR)
    {
        cout << "Listen failed." << portnumber;
        closesocket(ListenSocket);
        ListenSocket = INVALID_SOCKET;
        WSACleanup();
    }
    ClientSocket = accept(ListenSocket, NULL, NULL);
    if (ClientSocket == INVALID_SOCKET)
    {
        cout << "Socket accept failed." << portnumber;
        WSACleanup();
    }

    sockaddr test;
    int a = sizeof(test);
    cout << "getpeername() return value : " << getpeername(ClientSocket, &test, &a) << endl;
    cout << "test.sa_data : " << test.sa_data;


    StartReceive(ReceiveMessage, ClientSocket);
    strcpy(SendMessage,"Congratulations!! You have successfully transfered some data to G DA.");
    StartSend(SendMessage, ClientSocket);
    StartSend(portnumber, ClientSocket);
    InitialResult = shutdown(ClientSocket, SD_SEND);
    if (InitialResult == SOCKET_ERROR)
    {
        cout << "Shut down failed." << portnumber;
        closesocket(ClientSocket);
        WSACleanup();
    }
    closesocket(ClientSocket);
    closesocket(ListenSocket);
    WSACleanup();
}
+1  A: 

Why do you think WSADATA should be a char [14]? It's a struct as shown e.g. in these docs.

And BTW, in the various error cases you check, you should terminate the whole function (e.g. with a return), while what you're doing appears to be just to continue, after some message, with structures &c known to be invalid...

Edit: oh I see, when you say sa_data you mean test.sa_data, and another answer explained why it's not what you expect. Leaving this answer in anyway since at least the second paragraph is pretty important (and still relevant;-).

Alex Martelli
+2  A: 

Second and third arguments of accept(2) allow you to get that information without extra call to getpeername(2). Then you need to convert binary address to string representation with something like inet_ntoa(3).

Nikolai N Fetissov
A: 

The sa_data doesn't return char[14] of the type "xxx.xxx.xxx.xxx"

It isn't specified to do that, so no wonder it doesn't.

You need to look into sockaddr_in and sockaddr_in6.

EJP