C++ Server Controller

Moderators: Xymph, NADEO

Post Reply
MadMatt01
Posts: 23
Joined: 23 Feb 2014, 23:25

C++ Server Controller

Post by MadMatt01 »

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:

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;
}
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
MadMatt01
Posts: 23
Joined: 23 Feb 2014, 23:25

Re: C++ Server Controller

Post by MadMatt01 »

Solved, must have been a small mistake somewhere xD

Matt
User avatar
TMarc
Posts: 15441
Joined: 05 Apr 2011, 19:10
Location: Europe
Contact:

Re: C++ Server Controller

Post by TMarc »

Great :3
Post Reply

Return to “General Tools”

Who is online

Users browsing this forum: No registered users and 0 guests