Проблема с получением IP-адреса клиента в серверной программе на основе winsock 2
Здравствуйте, я сделал эту программу на основе учебника msdn winsock2.h. У меня есть серверная программа и клиентская. Все работает нормально, я даже сделал односторонний чат с сервера на клиент, больше похожий на трансляцию. Теперь я хочу увидеть IP-адрес клиента, когда он подключается. Я думаю, что сделал все правильно, но при каждом подключении он показывает разные адреса в странной форме, например 12.2.90.0, 12.2.46.0.
Это код сервера:
#include <cstdlib>
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <iphlpapi.h>
#define DEFAULT_PORT "27015"
using namespace std;
int main(int argc, char *argv[])
{
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct sockaddr_in client_info;
char * addr;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char buffer[50];
char typebuffer[50];
char connected_ip[15]= "\0";
int port;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
} cout<<"Winsock initialized..."<<endl;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
} else cout<<"Listening socket initialized...\nAccepting connections now..."<<endl;
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// Accept a client socket
ClientSocket = accept(ListenSocket, (struct sockaddr*)&client_info, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
} else
// converting the address in readable form
addr = inet_ntoa(client_info.sin_addr);
printf("Client connected, IP address is: %s\n", addr );
{
}
closesocket(ListenSocket);
for(;;)
{
cin.getline(typebuffer,50);
strcpy(buffer,"SERVER: ");
strcat(buffer,typebuffer);
send( ClientSocket, buffer, 50, 0 );
*buffer = '\0';
}
system("PAUSE");
return EXIT_SUCCESS;
}
1 ответ
Вы предоставляете sockaddr_in
структура для accept()
, но вы не говорите, насколько велика структура. Вы не обнуляете sockaddr_in
, а также accept()
не заполняется, так что вы получите случайные результаты при вызове inet_ntoa()
, Это поведение задокументировано:
Если
addr
и / илиaddrlen
равны NULL, то информация об удаленном адресе принятого сокета не возвращается.
addrlen
параметр не может быть NULL, если addr
параметр не равен NULL:
int addrlen = sizeof(client_info); // <-- Add this
ClientSocket = accept(ListenSocket, (struct sockaddr*)&client_info, &addrlen);