-1
我想讓我的服務器分配客戶端ID,但是每當我將客戶端連接到服務器時,服務器崩潰。Winsock2錯誤:連接到客戶端時服務器崩潰
服務器:
#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是哪個,然後當我需要發送的數據包對於客戶,我可以通過Address[ ID ];
參考客戶ID來完成。服務器和客戶端運行正常,沒有客戶端ID的代碼。請幫忙。任何關於如何改進代碼或其他方式來做到這一點的建議都沒有問題。
我認爲數組從0開始不是一個,所以當我定義MAX_CLIENTS爲2時,我在Max中遞減它,以便唯一可用的將是0和1.我將查看std :: map並改進代碼,而且我沒有考慮過使用同一個IP的客戶端,所以我一定會添加它。但我很好奇1如何無效? – NukingDragons 2014-09-18 22:39:47
如果您創建大小爲1的數組,則其中唯一的索引爲0,因爲索引從零開始。如果你有一個大小爲1的數組,那麼唯一有效的索引是[0]。如果你有一個大小爲2的數組,那麼有效索引是在[0]和[1]。 – 2014-09-18 22:44:42
好的。我認爲如果我把1放進去,它會允許0和1,如果我把0放進去,它只會是0.所以我認爲我輸入的數字是它可以達到的最大值。感謝您指點我正確的方向 – NukingDragons 2014-09-18 22:48:02