Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ IP Network Sockets
I created a client server program in c++ console. i run the server and then run the client. The server is not receiving the clients ip address.
 
here is the server code:
#include "stdafx.h"
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
 
int recvTimeOutTCP(SOCKET socket, long sec, long usec)
{
    struct timeval timeout;
    struct fd_set fds;
 
    timeout.tv_sec = sec;
    timeout.tv_usec = usec;
    // Setup fd_set structure
    FD_ZERO(&fds);
    FD_SET(socket, &fds);
    return select(0, &fds, 0, 0, &timeout);
}
 
int main(int argc, char **argv)
{
            WSADATA wsaData; 
            SOCKET ListeningSocket, NewConnection; 
            SOCKADDR_IN ServerAddr, SenderInfo; 
            int Port = 7171;
            // Receiving part
            char recvbuff[1024];
            int ByteReceived, i, nlen, SelectTiming;
           
            // Initialize Winsock version 2.2
            if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
            {
                 printf("Server: WSAStartup failed with error %ld.\n", WSAGetLastError());
                 // Exit with error
                 return 1;
            }
            else
            {
				printf("Server: The Winsock DLL found!\n");
                printf("Server: The current status is %s.\n\n", wsaData.szSystemStatus);
            }
           
            if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2 )
            {
                 // Tell the user that we could not find a usable WinSock DLL
                 printf("Server: The dll do not support the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion),HIBYTE(wsaData.wVersion));
                 // Do the clean up
                 WSACleanup();
                 // and exit with error
                 return 1;
            }
            else
            {
                 printf("Server: The dll supports the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion),HIBYTE(wsaData.wVersion));
              %u.%u\n\n", LOBYTE(wsaData.wHighVersion), HIBYTE(wsaData.wHighVersion));
            }
           
            // Create a new socket to listen for client connections.
            ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
           
            // Check for errors to ensure that the socket is a valid socket.
            if (ListeningSocket == INVALID_SOCKET)
            {
				printf("Server: Error at socket, error code: %ld.\n", WSAGetLastError());
				// Clean up
				WSACleanup();
				// and exit with error
				return 1;
            }
            else
			{
				printf("Server: socket is ok!\n");
			}
 
            // The IPv4 family
            ServerAddr.sin_family = AF_INET; //AF_INET tells Winsock we are using the IP address family.
            // host-to-network byte order
            ServerAddr.sin_port = htons(Port);
            // Listen on all interface, host-to-network byte order
            ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
           
            // Associate the address information with the socket using bind.
            // Call the bind function, passing the created socket and the sockaddr_in
            // structure as parameters. Check for general errors.
            if (bind(ListeningSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR)
            {
				printf("Server: bind failed! Error code: %ld.\n", WSAGetLastError());
				// Close the socket
				closesocket(ListeningSocket);
				// Do the clean up
				WSACleanup();
				// and exit with error
				return 1;
            }
            else
			{
				printf("Server: bind is working\n");
			}
 
            // Listen for client connections with a backlog of 5
            if (listen(ListeningSocket, 5) == SOCKET_ERROR)
            {
				printf("Server: listen: Error listening on socket %ld.\n", WSAGetLastError());
				// Close the socket
				closesocket(ListeningSocket);
				// Do the clean up
				WSACleanup();
				// Exit with error
				return 1;
            }
            else
			{
				printf("Server: listening for connections...\n\n");
			}
           
            // Set 10 seconds 10 useconds timeout
            SelectTiming = recvTimeOutTCP(ListeningSocket, 10, 10);
           
            switch (SelectTiming)
            {
                        case 0:
                              // Timed out, do whatever you want to handle this situation
                               printf("\nServer: Timeout over while waiting client!...");
                               break;
 
                        case -1:
                             // Error occurred, more tweaking here and the recvTimeOutTCP()...
                             printf("\nServer: Some error encountered with code number: %ld\n", WSAGetLastError());
                             break;
 
                        default:
							{
								// Accept a new connection when available. 'while' always true
								while(1)
								{
									// Reset the NewConnection socket to SOCKET_ERROR
									// Take note that the NewConnection socket in not listening
									NewConnection = SOCKET_ERROR;
									// While the NewConnection socket equal to SOCKET_ERROR
									// which is always true in this case...
									while(NewConnection == SOCKET_ERROR)
					NewConnection = accept(ListeningSocket, NULL, NULL);
										printf("Server: accept is working...\n");
										printf("Server: New client got connected, ready to receive and send data...\n\n");
 
									ByteReceived = recv(NewConnection, recvbuff, sizeof(recvbuff), 0);
 
										// When there is data
										if ( ByteReceived > 0 )
										{
											printf("Server: recv is working....\n");
 
											// Some info on the receiver side...
											getsockname(ListeningSocket, (SOCKADDR *)&ServerAddr, (int *)sizeof(ServerAddr));
											printf("Server: Receiving IP(s) from client: %s\n", inet_ntoa(ServerAddr.sin_addr)); 
																printf("Server: Receiving port from client: %d\n", htons(ServerAddr.sin_port));
 
																																	memset(&SenderInfo, 0, sizeof(SenderInfo));
											nlen = sizeof(SenderInfo);
 
											getpeername(NewConnection, (SOCKADDR *)&SenderInfo, &nlen);
											printf("Server: Sending IP used: %s\n", inet_ntoa(SenderInfo.sin_addr));
											printf("Server: Sending port used: %d\n", htons(SenderInfo.sin_port));
 
											
											printf("Server: Bytes received: %d\n", ByteReceived);
											
											printf("Server: Those bytes are: \"");
											
											for(i=0;i < ByteReceived;i++)
											{
												printf("%c", recvbuff[i]);
											}
											printf("\"");
										}
										// No data
										else if ( ByteReceived == 0 )
										{
											printf("Server: Connection closed!\n");
										}
										// Others
										else
										{
											printf("Server: recv failed with error code: %d\n", WSAGetLastError());
										}
									}
 
									
									if( shutdown(NewConnection, SD_SEND) != 0)
										printf("\n\nServer: Well, there is something wrong with the shutdown. The error code: %ld\n", WSAGetLastError());
									else
										printf("\nServer: shutdown is working...\n");
 
									
									
								//	if( recvTimeOutTCP(ListeningSocket, 10, 0) == 0)
										//break;
								}
							}
			}
 

            printf("\n\nServer: The listening socket is timeout...\n");
            if(closesocket(ListeningSocket) != 0)
			{
				printf("Server: Cannot close \"ListeningSocket\" socket. Error code: %ld\n", WSAGetLastError());
			}
            else
			{
				printf("Server: Closing \"ListeningSocket\" socket...\n");
			}
 
            if(WSACleanup() != 0)
			{
				printf("Server: WSACleanup failed! Error code: %ld\n", WSAGetLastError());
			}
            else
			{
				printf("Server: WSACleanup is working...\n");
			}
 
            return 0;
}
 
and here's the client:
#include "stdafx.h"

#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
 
using namespace std;
 
int main(int argc, char **argv)
{
            WSADATA wsaData;
            SOCKET SendingSocket;
            // Server/receiver address
            SOCKADDR_IN ServerAddr, ThisSenderInfo;
            // Server/receiver port to connect to
            unsigned int Port = 7171;
            int RetCode;
            // Be careful with the array bound, provide some checking mechanism...
            char sendbuf[1024] = "This is a test string from client";
            int BytesSent, nlen;
 
            // Initialize Winsock version 2.2
            WSAStartup(MAKEWORD(2,2), &wsaData);
            printf("Client: Winsock DLL status is %s.\n", wsaData.szSystemStatus);
           
            // Create a new socket to make a client connection.
            // AF_INET = 2, The Internet Protocol version 4 (IPv4) address family, TCP protocol
            SendingSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
            if(SendingSocket == INVALID_SOCKET)
            {
				printf("Client: socket failed! Error code: %ld\n", WSAGetLastError());
				// Do the clean up
				WSACleanup();
				// Exit with error
				return -1;
            }
            else
			{
				printf("Client: socket is ok!\n");  
			}
           
            // Set up a SOCKADDR_IN structure that will be used to connect
            // to a listening server on port 5150. For demonstration
            // purposes, let's assume our server's IP address is 127.0.0.1 or localhost
 
            // IPv4
            ServerAddr.sin_family = AF_INET;
            // Port no.
            ServerAddr.sin_port = htons(Port);
            // The IP address
            ServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
           
            // Make a connection to the server with socket SendingSocket.
            RetCode = connect(SendingSocket, (SOCKADDR *) &ServerAddr, sizeof(ServerAddr));
            if(RetCode != 0)
            {
				printf("Client: connect failed! Error code: %ld\n\n", WSAGetLastError());
				// Close the socket
				closesocket(SendingSocket);
				// Do the clean up
				WSACleanup();
				// Exit with error
				return -1;
            }
            else
            {
				printf("Client: got connected...\n");
				printf("Client: Ready for sending and/or receiving data...\n\n");
            }
           
            // At this point you can start sending or receiving data on
            // the socket SendingSocket.
 
            // Some info on the receiver side...
            getsockname(SendingSocket, (SOCKADDR *)&ServerAddr, (int *)sizeof(ServerAddr));
            printf("Client: Server IP(s) used: %s\n", inet_ntoa(ServerAddr.sin_addr));
            printf("Client: Server port used: %d\n\n", htons(ServerAddr.sin_port));
			
            // Sends some data to server/receiver...
            BytesSent = send(SendingSocket, sendbuf, strlen(sendbuf), 0);
 
            if(BytesSent == SOCKET_ERROR)
			{
				printf("Client: send error %ld.\n", WSAGetLastError());
			}
            else
            {
				printf("Client: message sent ok - bytes sent: %ld\n", BytesSent);
				// Some info on this sender side...
				// Allocate the required resources
				memset(&ThisSenderInfo, 0, sizeof(ThisSenderInfo));
				nlen = sizeof(ThisSenderInfo);
 
				getsockname(SendingSocket, (SOCKADDR *)&ThisSenderInfo, &nlen);
				printf("Client: Client IP(s) used: %s\n", inet_ntoa(ThisSenderInfo.sin_addr));
				printf("Client: Client port used: %d\n", htons(ThisSenderInfo.sin_port));
				printf("Client: Bytes message is: \"%s\"\n", sendbuf);
            }
 
            if( shutdown(SendingSocket, SD_SEND) != 0)
			{
				printf("Client: There is something wrong with the shutdown. The error code: %ld\n", WSAGetLastError());
			}
            else
			{
				printf("\nClient: shutdown working...\n");
			}
            // When you are finished sending and receiving data on socket SendingSocket,
            // you should close the socket using the closesocket API. We will
            // describe socket closure later in the chapter.
            if(closesocket(SendingSocket) != 0)
			{
				printf("Client: Cannot close \"SendingSocket\" socket. Error code: %ld\n", WSAGetLastError());
			}
            else
			{
				printf("Client: Closing \"SendingSocket\" socket...\n");
			}
 
            // When your application is finished handling the connection, call WSACleanup.
            if(WSACleanup() != 0)
			{
				printf("Client: WSACleanup failed!...\n");
			}
            else
			{
				printf("Client: WSACleanup worked...\n");
			}
 
            return 0;
}
 
a line in the output of the server is: Server: Receiving IP(s) from client: 0.0.0.0
how do i get the IP address of the computer the client is running on?
Posted 11-Mar-13 2:40am

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

The client IP address is obtained from the socket returned by the accept() function[^]. Your code is trying to get it from the listening socket.
  Permalink  
Comments
Member 8589499 at 11-Mar-13 8:04am
   
so what do i need to change in my code to fix it?
Richard MacCutchan at 11-Mar-13 8:10am
   
Use the values from the returned socket. I gave you a link to the documentation where it is explained.
Member 8589499 at 11-Mar-13 8:29am
   
i don't really understand what i need to do. other websites mention a getpeername() function?
Richard MacCutchan at 11-Mar-13 8:53am
   
Read the documentation, like I suggested, it explains how to do it.
Member 8589499 at 11-Mar-13 9:42am
   
i have read the document and it doesn't help me. I am accepting the socket. I am using similar lines from the document. changing the socket in this line getsockname(ListeningSocket, (SOCKADDR *)&ServerAddr, (int *)sizeof(ServerAddr));
doesn't do anything
Lukasz Gwizdz (Member 2097797) at 11-Mar-13 9:44am
   
Richard is right. Moreover, keep in mind that getsockname() is for local socket, and getpeername() is for remote. And one more thing, 0.0.0.0 is ANY (INADDR_ANY) address, the address which server is bound to (this info is sufficient to figure out what's wrong). For the first look, you are doing everything fine (getsockname for server's ListeningSocket, and getpeername for remote's NewConnection).
You printing info about server listening socket as it would be remote connected socket.
Eg.:
printf("Server: Receiving port from client: %d\n", htons(ServerAddr.sin_port));
ServerAddr.sin_port is not client port, this is port of server's listening socket.
This is remote port:
printf("Server: Sending port used: %d\n", htons(SenderInfo.sin_port));
ServerAddr stores data about server, and SenderInfo about connected remote peer (client). So, I think that your expectations about output log are wrong.
You just need to change your log output. "Sending IP..." should become "Receiving IP..."
Member 8589499 at 11-Mar-13 9:48am
   
so there's no way to change the 0.0.0.0?
Lukasz Gwizdz (Member 2097797) at 11-Mar-13 9:58am
   
I'm not sure what are you trying to accomplish.
I think that phrase "from client" in this context is misleading.
Change the wording. Eg. something like this:
 
// print info about server, it is sufficient to print it once
printf("Server: Server is listening on: %s:%d\n", inet_ntoa(ServerAddr.sin_addr), htons(ServerAddr.sin_port));
 
// print info about client
printf("Server: Connected peer: %s:%d\n", inet_ntoa(SenderInfo.sin_addr), htons(SenderInfo.sin_port)); // or "Received connection from: %s:%d\n"
Richard MacCutchan at 11-Mar-13 10:09am
   
I repeat read the documentation. You cannot get the IP address from the ListeningSocket, you get it from the socket that is returned by the accept() call. I really don't know what else I can say on this.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 575
1 Kornfeld Eliyahu Peter 409
2 Maciej Los 369
3 DamithSL 196
4 OriginalGriff 188
0 OriginalGriff 6,353
1 DamithSL 4,854
2 Maciej Los 4,476
3 Kornfeld Eliyahu Peter 4,058
4 Sergey Alexandrovich Kryukov 3,917


Advertise | Privacy | Mobile
Web01 | 2.8.141223.1 | Last Updated 11 Mar 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100