C++ Server Controller
Posted: 22 Aug 2020, 12:25
Hey all, I'm just experimenting with C++ to see if I can get a program to communicate with the dedicated server on port 5002, unfortunately however the dedicated server does not seem to respond to any xml-rpc commands whatsoever, I've tried everything, including trying every xml-rpc example for C++ and C, but to no avail, the closest I have gotten is this:
Which is able to return the GbxRemote format (2), but when I try and authenticate with SuperAdmin and password, the dedicated server does nothing, and as there is no response on the dedicated server end, the program exits with code 10054 (peer kills the socket). With Uaseco, it shows every xml-rpc command (I have the verbosexmlrpc flag turned on) that it throws at it, and yet nothing with the C++ program... I'm hoping somebody on here has some experience with this sort of stuff (or if I'm doing something really obvious wrong xD) and could give me a hand. If anybody is wondering, the original code is from a C++ controller called ManiaPP, but it is obsolete and only worked with Linux (or so it is said, as this doesn't work for me unless this was a Linux thing where it wasn't so picky) so I changed most of this code to work with Windows (WinSock2) and if I can get this working, I will fork it from here and create a controller for Windows.
Matt
Code: Select all
#include "TcpClient.h"
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
WSADATA wsaData;
SOCKET SendingSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char recvbuf[512];
int iResult;
int iResultt;
int recvbuflen = 512;
long RequestHandle = 0x80000000;
TcpClient::TcpClient()
{
// Server/receiver address
}
void TcpClient::Close()
{
closesocket(SendingSocket);
// Do the clean up
WSACleanup();
}
bool TcpClient::Connect(std::string address, int port)
{
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo("localhost", "5002", &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
// Create a SOCKET for connecting to server
SendingSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (SendingSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect(SendingSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(SendingSocket);
SendingSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (SendingSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
}
bool TcpClient::Send(std::string data)
{
//const char* messageData = data.c_str();
//authenticate with dedicated server
const char* messageData = "<?xml version=\"1.0\" encoding=\"utf-8\"?><methodCall><methodName><![CDATA[Authenticate]]></methodName><params><param><value><string><![CDATA[SuperAdmin]]></string></value></param><param><value><string><![CDATA[password]]></string></value></param></params></methodCall>";
//unsigned long dataLength = (strlen(messageData));
//unsigned long messageLength = (dataLength + 8);
//char message[messageLength];
//memcpy(&message[0], &dataLength, 4);
//memcpy(&message[4], &RequestHandle, 4);
//memcpy(&message[8], messageData, dataLength);
std::cout << messageData;
//for(;;)
// Send an initial buffer
iResult = send(SendingSocket, messageData, (int)strlen(messageData), 0 );
std::cout << strlen(messageData);
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(SendingSocket);
WSACleanup();
return false;
}
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection since no more data will be sent
/*iResult = shutdown(SendingSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(SendingSocket);
WSACleanup();
return false;
}*/
/*getsockname(SendingSocket, (SOCKADDR *)&ServerAddr, (int *)sizeof(ServerAddr));
printf("Client: Receiver IP(s) used: %s\n", inet_ntoa(ServerAddr.sin_addr));
printf("Client: Receiver port used: %d\n", htons(ServerAddr.sin_port));
while(bytes_to_write > 0)
{
int send_return = send(SendingSocket, message, bytes_to_write, 0);
if(send_return == SOCKET_ERROR)
{
perror("Send failed : ");
return false;
}
std::cout << bytes_to_write << std::endl << send_return;
bytes_to_write -= send_return;
if(bytes_to_write == 0)
break;
memcpy(message, (message + send_return), bytes_to_write);
}*/
//message[7] = 0x80;
return true;
}
std::string TcpClient::Receive(int size = 512)
{
if(SendingSocket == -1)
return NULL;
std::string received;
received.resize(size);
int bytes_received = 0;
while(bytes_received < size)
{
iResultt = recv(SendingSocket, &received[bytes_received], (size - bytes_received),0);
if ( iResultt > 0 )
printf("Bytes received: %d\n", iResultt);
else if ( iResultt == 0 )
printf("Connection closed\n");
else
{
printf("recv failed with error: %d\n", WSAGetLastError());
break;
}
bytes_received += iResultt;
std::cout << received;
}
received[bytes_received] = 0;
return received;
}
bool TcpClient::SearchForCallBacks(int timeout)
{
fd_set readfds;
struct timeval tv;
FD_ZERO(&readfds);
FD_SET(sock, &readfds);
tv.tv_sec = 0;
tv.tv_usec = 2;
int selectResult = select((sock + 1), &readfds, NULL, NULL, &tv);
if(selectResult > 0)
{
return true;
}
return false;
}
Matt