#include
#include
#define WSAErr() do{cerr << "WSAError: " << WSAGetLastError() << endl;}while(false)
#define PORT 27015
//lets not rape the global namespace or compiler with 'úsing namespace std;'
using std::cout;
using std::cerr;
using std::cin;
using std::endl;
inline bool InitSock()
{
#if PLATFORM == PLATFORM_WIN
WSADATA WsaData;
return WSAStartup(MAKEWORD(2,2), &WsaData) == NO_ERROR;
#else
return true;
#endif
}
inline void StopSock()
{
#if PLATFORM == PLATFORM_WIN
WSACleanup();//just btw, this can fail too, just like WSAStartup...
#endif
}
class Address
{
public:
Address()
{
address = 0;//and port?
}
//i'd say use inet_addr here, much safer and easier :)
Address( unsigned int a, unsigned int b, unsigned int c, unsigned int d, unsigned short prt )
{
address = (a << 24) | (b << 16) | (c << 8) | d;
port = prt;
}
//hint: initializer lists allow this without funny na
Address( unsigned int addrss, unsigned short prt )
{
address = addrss;
port = prt;
}
unsigned int GetAddress() const//technically an IP is an unsigned long
{
return address;
}
unsigned short GetPort() const
{
return port;
}
private:
unsigned int address;
unsigned short port;
};
class Socket
{
public:
Socket()
{
handle = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
if (handle == INVALID_SOCKET)
WSAErr();
}
bool Open( unsigned short port )
{
//set our ports etc
sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(port);
int result = bind(handle,(const sockaddr*) &address,sizeof(sockaddr_in));
if(result == SOCKET_ERROR)//incase another value below zero gets reserved to mean something other than 'érror'
WSAErr();
#if PLATFORM == PLATFORM_MAC || PLATFORM == PLATFORM_UNI
//int nonblocking = 1;
//if (fcntl( handle, F_SETFL, O_NONBLOCK, nonblocking)== -1)
//{
//cout<<"SOCKET FAILED TO SET NON-BLOCKING\n";
//}
#elif PLATFORM == PLATFORM_WIN
DWORD nonblocking = 1;
if (ioctlsocket(handle,FIONBIO,&nonblocking) !=0)
{
cout<<"SOCKET FAILED TO SET NON-BLOCKING\n";
WSAErr();
}
#endif
//return result;
return 0;
}
void Close()
{
#if PLATFORM == PLATFORM_MAC || PLATFORM == PLATFORM_UNI
//close( socket );
#elif PLATFORM == PLATFORM_WIN
closesocket( socket );
#endif
}
bool Send( const Address & destination, const char * data, int size )
{
unsigned int dest_addr = destination.GetAddress();
unsigned short dest_port = destination.GetPort();
sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(dest_addr);
address.sin_port = htons(dest_port);
int sent_bytes = sendto( handle, data, size, 0, (sockaddr*)&address, sizeof(address) );
if ( sent_bytes < size || handle == INVALID_SOCKET)//why would the socket explode after?
{
WSAErr();
return false;
}
return true;
}
int Receive( Address & sender, void * data, int size )
{
#if PLATFORM == PLATFORM_WIN
typedef int socklen_t; //if your gonna be 'fancy' with types, alteast use std::size_t...
#endif
socklen_t fromLength = sizeof(sockaddr_in);
sockaddr_in pAddr;
cout << "recieving data..." << endl;
int received_bytes = recvfrom( handle, (char*)data, size, 0, (sockaddr*)&pAddr, &fromLength);//this passed sender for the sockaddr...(the dangers of c-casts arise!)
if(received_bytes == SOCKET_ERROR)
{
WSAErr();
return -1;
}
sender = Address(pAddr.sin_addr.s_addr,pAddr.sin_port);//seeing as there are no set methods...
return received_bytes;
}
private:
SOCKET handle;
};
int client(Socket s)
{
cout<<"CLIENT\n";
const char d[] = "hello world!";
Address a = Address(127,0,0,1,PORT);//127.0.0.1 is localhost (127.0.0.0 is the windows system gateway)
s.Send(a, d, sizeof(d));
cin.get();
return 0;
}
int server(Socket s)
{
cout<<"SERVER\n";
while (true)
{
Address sender;
unsigned char buffer[1024];//this was an array of 1024 char pointers...
int br = s.Receive(sender, buffer, sizeof(buffer));//this passed a pointer to the array, instead or a pointer the the first element...
if (br > 0)
{
cout << "Data Recived..." << endl;//debugging messages ftw!
for (int i = 0; i < br; i++)
{
cout << buffer[i];
}
cout<<"\n";
}
else
WSAErr();//errors wheren't checked, which resulted in error 10014 being unnoticed...
}
return 0;
}
int main(int argc, char *argv[])
{
if (!InitSock())
{
return 1; //if there is an error return 1!
}
//sockets init
Socket s;
//socket opened on port g_port;
//cout< 1)
{
if (strcmp(argv[1],"-s") == 0)
{
//this was in the wrong place, causing double+ binding of the same port, again a WSAError will tell you this ;)
int res = s.Open(PORT);
if (res < 0)
{
WSAErr();
cin.get();
return 1;
}
server(s);
}
else
{
client(s);
}
}
else
{
client(s);
}
s.Close();
StopSock();
return 0;
}
No comments available.
Add new comment