我正在尝试让我的服务器分配客户端ID,但每当我将客户端连接到服务器时,服务器都会崩溃。
服务器:
#include <iostream>
#include <winsock2.h>
#include <string>
#define PORT 25444
#define MAX_CLIENTS 2
#define BUFLEN 512
int main()
{
SOCKET s;
unsigned int Max = MAX_CLIENTS - 1;
unsigned int ID[ Max ];
std::string Address[ Max ];
struct sockaddr_in server, si_other;
int slen, recv_len;
char buf[ BUFLEN ];
WSADATA wsa;
slen = sizeof( si_other );
if ( WSAStartup( MAKEWORD( 2, 2 ), & wsa ) != 0 )
{
std::cout << "NETWORK ERROR: Failed to initialise. Error code: " << WSAGetLastError() << "\n";
}
if ( ( s = socket( AF_INET, SOCK_DGRAM, 0 ) ) == INVALID_SOCKET )
{
std::cout << "NETWORK ERROR: Failed to create socket. Error code: " << WSAGetLastError() << "\n";
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( PORT );
if ( bind( s, ( struct sockaddr * ) & server, sizeof( server ) ) == SOCKET_ERROR )
{
std::cout << "NETWORK ERROR: Failed to bind to port. Error Code: " << WSAGetLastError() << "\n";
}
while( 1 )
{
bool AddClient;
unsigned int TimesLooped;
memset( buf, '\0', BUFLEN );
if ( ( recv_len = recvfrom( s, buf, BUFLEN, 0, ( struct sockaddr * ) & si_other, & slen ) ) == SOCKET_ERROR )
{
std::cout << "NETWORK ERROR: Failed to read from the port. Error code: " << WSAGetLastError() << "\n";
}
else
{
TimesLooped = 0;
for ( int i = 0; i <= Max; i++ )
{
if ( inet_ntoa( si_other.sin_addr ) != Address[ i ] )
{
AddClient = true;
}
else
{
AddClient = false;
i = Max;
}
TimesLooped++;
}
if ( AddClient )
{
Address[ TimesLooped ] = inet_ntoa( si_other.sin_addr );
ID[ TimesLooped ] = TimesLooped;
}
}
std::cout << "NETWORK: Received packet from " << inet_ntoa( si_other.sin_addr ) << ":" << ntohs( si_other.sin_port ) << "( Client ID: " << ID[ TimesLooped ] << " )" << "\n";
std::cout << "NETWORK: Data: " << buf << "\n";
if ( sendto( s, buf, recv_len, 0, ( struct sockaddr * ) & si_other, slen ) == SOCKET_ERROR )
{
std::cout << "NETWORK ERROR: Failed to send data through the port. Error code: " << WSAGetLastError() << "\n";
}
}
closesocket( s );
WSACleanup();
return 0;
}
客户端:
#include <string>
#include <iostream>
#include <winsock2.h>
#define IP "127.0.0.1"
#define PORT 25444
#define BUFLEN 512
using namespace std;
void SendPacket( string message )
{
struct sockaddr_in si_other;
int s, slen = sizeof( si_other );
char buf[ BUFLEN ];
char msg[ BUFLEN ];
strcpy( msg, message.c_str() );
WSADATA wsa;
if ( WSAStartup( MAKEWORD( 2, 2 ), & wsa ) != 0 )
{
cout << "ERROR: Network failed to initialise. Error code: " << WSAGetLastError() << "\n";
}
if ( ( s = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == INVALID_SOCKET )
{
cout << "ERROR: Network failed to create socket. Error code: " << WSAGetLastError() << "\n";
}
memset( ( char * ) & si_other, 0, sizeof( si_other ) );
si_other.sin_family = AF_INET;
si_other.sin_port = htons( PORT );
si_other.sin_addr.S_un.S_addr = inet_addr( IP );
if ( sendto( s, msg, strlen( msg ), 0, ( struct sockaddr * ) & si_other, slen ) == SOCKET_ERROR )
{
cout << "ERROR: Network failed to send data through the port. Error code: " << WSAGetLastError() << "\n";
}
memset( buf, '\0', BUFLEN );
if ( recvfrom( s, buf, BUFLEN, 0, ( struct sockaddr * ) & si_other, & slen ) == SOCKET_ERROR )
{
cout << "ERROR: Network failed to read from the port. Error code: " << WSAGetLastError() << "\n";
}
closesocket( s );
WSACleanup();
}
int main()
{
SendPacket( "Test" );
return 0;
}
我希望能够拥有客户端ID,以便我可以跟踪哪个IP是哪个,然后当我需要向客户端发送数据包时,我可以通过{{1引用客户端ID来实现}}。服务器和客户端运行良好,没有客户端ID的代码。请帮忙。有关如何改进代码或其他方法的任何建议都很好。
答案 0 :(得分:0)
在您的代码中,您的Address数组只有一个元素。 MAX_CLIENTS为2. Max为2 - 1或1,因此只有Address [0]有效。你从0循环到1,所以每次你引用索引1时,我都不会惊讶地看到崩溃。
看看std :: map,例如here.字典将处理搜索。我会使用std :: map来处理客户端ID表。
此外,您的客户端密钥仅使用IP地址,而不是客户端端口。如果两个客户端从同一IP地址连接,则它们将共享您的客户端ID。您可能希望在ID字符串中包含端口号。