ОС : Ubuntu (Linux) Below is my class Server . There is a void myListen() method in which I try to extract server and client IPs. With the client, everything goes, but the server's IP address seems to me as 0.0.0.0 , which, of course, does not suit me. How to get a real ip to which the client is connected?
class Server{ private: int sockfd, newsockfd, portno, pid; struct sockaddr_in serv_addr, cli_addr, *tmp_addr_in; socklen_t clilen, servlen; struct sockaddr *tmp_addr; public: Server(int port) : portno(port) { sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding"); } ~Server(){ close(sockfd); } void myListen(){ listen(sockfd,5); clilen = sizeof(cli_addr); char bufClientIp[64]; char bufServerIp[64]; while (1) { newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); inet_ntop(AF_INET, &cli_addr.sin_addr, bufClientIp, INET_ADDRSTRLEN); struct sockaddr sa; servlen = sizeof(tmp_addr); if(getsockname(sockfd, &sa, &servlen) == -1){ error("ERROR on getsockname"); } tmp_addr_in = (sockaddr_in*)tmp_addr; inet_ntop(AF_INET, &(tmp_addr_in->sin_addr), bufServerIp, INET_ADDRSTRLEN); std::cout<<"Server -> "<<bufServerIp<<std::endl; std::cout<<"Client -> "<<bufClientIp<<std::endl; if (newsockfd < 0) error("ERROR on accept"); pid = fork(); if (pid < 0) error("ERROR on fork"); if (pid == 0) { while(1){ close(sockfd); myReceive(); } exit(0); } else close(newsockfd); } /* end of while */ } void myReceive (){ int bitsReceived; char buffer[256]; bzero(buffer,256); bitsReceived = read(newsockfd, buffer, 255); if (bitsReceived < 0) error("ERROR reading from socket"); printf("Here is the message: %s\n", buffer); bitsReceived = write(newsockfd,"I got your message",18); if (bitsReceived < 0) error("ERROR writing to socket"); } }; DECISION :
Based on the example of Mr. avp, I changed my void myListen() function to a working state and in the private section I changed the type cli_addr from struct sockaddr_in to struct sockaddr :
void myListen(){ listen(sockfd,5); std::string szClientIp; std::string szServerIp; int szClientPort; int szServerPort; while (1) { newsockfd = accept(sockfd, &cli_addr, &clilen); if (getpeername(newsockfd, &cli_addr, &clilen) == -1) perror("getpeername"); else szClientIp = inet_ntoa(((struct sockaddr_in *)&cli_addr)->sin_addr); szClientPort = ntohs(((struct sockaddr_in *)&cli_addr)->sin_port); std::cout<<"Client Ip : > "<<szClientIp<<std::endl; std::cout<<"Client Port : > "<<szClientPort<<std::endl; if (getsockname(newsockfd, &cli_addr, &clilen) == -1) perror("getsockname"); else szServerIp = inet_ntoa(((struct sockaddr_in *)&cli_addr)->sin_addr); szServerPort = ntohs(((struct sockaddr_in *)&cli_addr)->sin_port); std::cout<<"Server Ip : > "<<szServerIp<<std::endl; std::cout<<"Server Port : > "<<szServerPort<<std::endl; if (newsockfd < 0) error("ERROR on accept"); pid = fork(); if (pid < 0) error("ERROR on fork"); if (pid == 0) { while(1){ close(sockfd); myReceive(); } exit(0); } else close(newsockfd); } /* end of while */