c – 确定服务器上已连接客户端的IP地址
作者:互联网
我有一台服务器在一台机器上运行,并将其使用的端口转发到我的路由器,另一台运行客户端的机器使用ISP分配的外部IP地址而不是本地地址连接到服务器.这一切工作正常,它连接,但当我检查连接的套接字(客户端)的地址时,它显示的IP地址是完全不同的?它显示我148.49.68.0.我在ipconfig上找不到这个,也不明白这是从哪里出来的.客户端不应该显示我的外部地址吗? (看到两台计算机使用相同的外部IP地址).
[编辑]添加了服务器源
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <string.h>
using namespace std;
int PORT;
const int winsock_version = 2;
const int max_con = 10;
string SERVER_ADDRS;
void Bind(SOCKET &serv,struct sockaddr_in &serv_info,int size);
void Listen(SOCKET &serv,int max_con);
void connection_info(struct sockaddr_in &client);
bool communication(SOCKET &client);
SOCKET Accept(SOCKET &serv);
int main(void){
WSADATA wsadata;
if ( WSAStartup(MAKEWORD(winsock_version,0),&wsadata) == 0 ){
cout<<"-[Initialized.]" << endl;
cout<<"-[Server Address (leave blank to scan for all IP's)]: ";
getline(cin,SERVER_ADDRS);
cout<<"-[Port]: ";
cin>>PORT;
struct sockaddr_in serv_info;
serv_info.sin_family = AF_INET;
serv_info.sin_port = htons(PORT);
if( sizeof(SERVER_ADDRS) > 5 ){
cout<<"-[Listening on: " << SERVER_ADDRS << "]" << endl;
serv_info.sin_addr.s_addr = inet_addr(SERVER_ADDRS.c_str());
}else{
cout<<"-[Scanning for All IP's]" << endl;
serv_info.sin_addr.s_addr = INADDR_ANY;
}
SOCKET serv;
serv = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if ( serv != INVALID_SOCKET ){
//------------------------------------------------------------
Bind(serv,serv_info,sizeof(serv_info));
Listen(serv,max_con);
struct sockaddr_in client_info;
int size = sizeof(client_info);
SOCKET client_sock = Accept(serv);
connection_info(client_info);
if (communication(client_sock) == true){
closesocket(serv);
closesocket(client_sock);
}
//------------------------------------------------------------
}
}else{
cout<<"-[Initialization failed, running cleanup.]" << endl;
}
if (WSACleanup() == 0){
cout<<"-[Cleanup Successful.]" << endl;
}
return 0;
}
void Bind(SOCKET &serv,struct sockaddr_in &serv_info,int size){
if ( bind(serv,(sockaddr*)&serv_info,size) != -1 ){
//Binding complete, now clear the port and allow for reuse if needed using setsockopt
char yes = '1';
if ( setsockopt(serv,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) != SOCKET_ERROR){
cout<<"-[Binding Successful.]" << endl;
}
}
}
void Listen(SOCKET &serv,int max_con){
if ( listen(serv,max_con) != -1 ){
cout<<"-[Listening for connections.] " << endl;
}
}
SOCKET Accept(SOCKET &serv){
struct sockaddr_in client_info;
int size = sizeof(client_info);
SOCKET recv;
recv = accept(serv,(sockaddr*)&client_info,&size);
if (recv != INVALID_SOCKET ) {
return recv;
}else{
cout<<"-[Invalid Socket.]" << endl;
}
}
void connection_info(struct sockaddr_in &client){
char *connected_ip= inet_ntoa(client.sin_addr);
int port = ntohs(client.sin_port);
cout<<"-[IP:" << connected_ip <<", Connected on PORT:"<< port << "]"<< endl;
}
bool communication(SOCKET &client){
cout<<"[---------------{CHAT}---------------]" << endl;
int bytes_in;
int bytes_out;
char recvd_text[80];
string send_text;
while(true){
cout<<"-[SERVER]: ";
getline(cin,send_text);
if (sizeof(send_text) > 0 ){
bytes_out = send(client,send_text.c_str(),send_text.length()+1,0);
cout<< endl;
if (bytes_out == SOCKET_ERROR){
cout<<"-[SERVER error in sending.]" << endl;
break;
}
}
bytes_in = recv(client,recvd_text,sizeof(recvd_text),0);
if (bytes_in > 0 ){
cout<<"-[CLIENT]: " << recvd_text << endl; //output on screen
}
if (bytes_in == 0){
cout<<"-[CLIENT has disconnected.]" << endl;
break;
}
if (bytes_in == SOCKET_ERROR){
cout<<"-[CLIENT closed unexpectedly.]" << endl;
break;
}
}
return true;
}
解决方法:
试试这个:
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <string>
int PORT;
const int winsock_version = 2;
const int max_con = 10;
std::string SERVER_ADDRS;
void Bind(SOCKET &serv, const struct sockaddr_in &serv_info);
void Listen(SOCKET &serv, int max_con);
void connection_info(struct sockaddr_in &client);
bool communication(SOCKET client);
SOCKET Accept(SOCKET serv, sockaddr_in &client_info);
int main(void)
{
WSADATA wsadata;
if ( WSAStartup(MAKEWORD(winsock_version,0),&wsadata) == 0 )
{
std::cout << "-[Initialized.]" << std::endl;
std::cout << "-[Server Address (leave blank to scan for all IP's)]: ";
std::getline(std::cin, SERVER_ADDRS);
std::cout << "-[Port]: ";
std::cin >> PORT;
struct sockaddr_in serv_info = {0};
serv_info.sin_family = AF_INET;
serv_info.sin_port = htons(PORT);
if( SERVER_ADDRS.length() > 0 )
{
std::cout << "-[Listening on: " << SERVER_ADDRS << "]" << std::endl;
serv_info.sin_addr.s_addr = inet_addr(SERVER_ADDRS.c_str());
}
else
{
std::cout << "-[Scanning for All IP's]" << std::endl;
serv_info.sin_addr.s_addr = INADDR_ANY;
}
SOCKET serv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if ( serv != INVALID_SOCKET )
{
//------------------------------------------------------------
Bind(serv, serv_info);
Listen(serv, max_con);
struct sockaddr_in client_info = {0};
SOCKET client_sock = Accept(serv, client_info);
if ( client_sock != INVALID_SOCKET )
{
connection_info(client_info);
communication(client_sock);
closesocket(client_sock);
}
//------------------------------------------------------------
closesocket(serv);
}
if (WSACleanup() == 0)
{
std::cout << "-[Cleanup Successful.]" << std::endl;
}
}
else
{
std::cout << "-[Initialization failed.]" << std::endl;
}
return 0;
}
void Bind(SOCKET serv, const struct sockaddr_in &serv_info)
{
//clear the port and allow for reuse before binding it
int yes = 1;
if ( setsockopt(serv, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(yes)) != SOCKET_ERROR)
{
std::cout << "-[Reuse Address Successful.]" << std::endl;
}
if ( bind(serv, (sockaddr*)&serv_info, sizeof(serv_info)) != -1 )
{
std::cout << "-[Binding Successful.]" << std::endl;
}
}
void Listen(SOCKET serv, int max_con)
{
if ( listen(serv, max_con) != -1 )
{
std::cout << "-[Listening for connections.] " << std::endl;
}
}
SOCKET Accept(SOCKET &serv, sockaddr_in &client_info)
{
int size = sizeof(client_info);
SOCKET recv = accept(serv, (sockaddr*)&client_info, &size);
if ( recv == INVALID_SOCKET )
{
std::cout << "-[Invalid Socket.]" << std::endl;
}
return recv;
}
void connection_info(struct sockaddr_in &client)
{
char *connected_ip = inet_ntoa(client.sin_addr);
int port = ntohs(client.sin_port);
st::cout << "-[IP:" << connected_ip << ", Connected on PORT:" << port << "]" << std::endl;
}
bool communication(SOCKET client)
{
std::cout << "[---------------{CHAT}---------------]" << std::endl;
int bytes_in;
int bytes_out;
char recvd_text[81];
std::string send_text;
while(true)
{
std::cout << "-[SERVER]: ";
std::getline(std::cin,send_text);
if (send_text.length() > 0 )
{
bytes_out = send(client, send_text.c_str(), send_text.length()+1, 0);
std::cout << std::endl;
if (bytes_out == SOCKET_ERROR)
{
std::cout << "-[SERVER error in sending.]" << std::endl;
break;
}
}
bytes_in = recv(client, recvd_text, sizeof(recvd_text)-1, 0);
if (bytes_in == SOCKET_ERROR)
{
std::cout << "-[CLIENT closed unexpectedly.]" << std::endl;
break;
}
else if (bytes_in == 0)
{
std::cout << "-[CLIENT has disconnected.]" << std::endl;
break;
}
else
{
recvd_text[bytes_in] = 0;
std::cout << "-[CLIENT]: " << recvd_text << std::endl; //output on screen
}
}
return true;
}
标签:winsock,c,ip,client-server,ip-address 来源: https://codeday.me/bug/20190726/1544793.html