你好我基于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;
}
答案 0 :(得分: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);