Excuse the code below, its copied and pasted from my main program so most of these headers could probably be snipped etc.
Code:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <vector>
#include <string>
#include <sys/time.h>
#include <arpa/inet.h>
using namespace std;
#define A2S_INFO "\xFF\xFF\xFF\xFF\x54Source Engine Query"
#define A2S_INFO_LENGTH 25
int main(int argc, char *argv[])
{
int sockfd, a, flags;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
flags = fcntl(sockfd, F_GETFL);
a = fcntl(sockfd, F_SETFL,O_NONBLOCK);
if (sockfd)
{
struct hostent *udptoaddr;
struct sockaddr_in udp_toaddr;
struct sockaddr_in udp_fromaddr;
unsigned int length;
string address;
int port;
address = "109.70.149.41";
port = 27000;
udp_toaddr.sin_family = AF_INET;
udptoaddr = gethostbyname(address.c_str());
if (udptoaddr == 0)
{
cout << "Host Error\n";
} else {
// Success!
}
bcopy((char *)udptoaddr->h_addr, (char *)&udp_toaddr.sin_addr, udptoaddr->h_length);
udp_toaddr.sin_port = htons(port);
struct timeval waitd;
fd_set sendfds;
FD_ZERO(&sendfds);
waitd.tv_sec = 2;
waitd.tv_usec = 0;
int err;
FD_SET(sockfd, &sendfds);
length=sizeof(struct sockaddr_in);
err = select(sockfd+1, NULL, &sendfds, (fd_set*)0, &waitd);
if (FD_ISSET(sockfd, &sendfds)) {
// Ready so send data
char sendbuf[80];
int result;
result = sendto(sockfd, A2S_INFO, A2S_INFO_LENGTH, 0, (const struct sockaddr *)&udp_toaddr, length );
if (result < 0) {
cout << "SEND RESULT (" << errno << "): " << strerror(errno) << "\n";
}
FD_CLR(sockfd, &sendfds);
// Now Perform another check and loop till data received.
bool data;
data = false;
while (!data) {
struct timeval waitd;
fd_set readfds;
FD_ZERO(&readfds);
waitd.tv_sec = 2;
waitd.tv_usec = 0;
int err;
FD_SET(sockfd, &readfds);
err = select(sockfd+1, &readfds, NULL, (fd_set*)0, &waitd);
if (FD_ISSET(sockfd, &readfds)) {
// Data Waiting
int result;
char buf1[1024];
result = recvfrom(sockfd, buf1, 1024, 0, (struct sockaddr *) &udp_fromaddr, &length);
cout << "Bytes Received: " << result << "\n";
string newbuf;
newbuf = buf1;
cout << "cout full buffer: " << newbuf << "\n";
cout << "Press any key to display char by char buffer\n";
cin.get();
int loop;
for (loop = 0; loop < result; loop++)
{
cout << buf1[loop] << "\n";
}
cout << "End of Char by Char Display\n";
// Received Packet. Send it back for parsing. but HOW?
FD_CLR(sockfd, &readfds);
data = true;
} else
{
// No DATA
bool data;
data = false;
}
}
} else
{
return -1;
}
} else {
return -1;
// Socket Error
}
};
This is the code so far in my testing cpp source file. As you can see, this version isnt using structs and such and relies on the basics to reduce problems with my other coding (if any). Try it out, Program will receive a UDP response from a Left4Dead2 server, display the output, then quit. This is to show you what im referring to, and the buffer that i need to parse and contain into a struct. Preferably with the struct being:
Code:
struct A2SReplyPacket{
unsigned char Type;
unsigned char Version;
char ServerName[256];
char Map[32];
char GameDirectory[32];
char GameDescription[256];
short AppID;
unsigned char Players;
unsigned char MaxPlayers;
unsigned char Bots;
unsigned char Dedicated;
unsigned char OS;
unsigned char Password;
unsigned char Secure;
char GameVersion[32];
};
If anyone could provide assistance id be extremely grateful. Starting to tear my hair out now ;(