I just created a UDP sockets program with a sender and reciever, and it works great on my own computer.
Then I asked my friend who uses OSX to compile it and see if we could send/recieve with eachother. It compiled, but it doesn''t send or recieve.
My friend is really busy, and I''m finding it really hard to debug it cause.. well, it works on my windows machine and I only have one machine, heh.
So, I have no idea what''s causing the problem. My guess is that somehow the way i''m using the sockets is not compatible with unix sockets, and I''ve been reading the man pages but can''t find any discrepencies.
Maybe someone here can look over the code and find the problem?
I have my code split into 4 files.
udp.h:
#ifndef __UDP_H__
#define __UDP_H__
#ifdef WIN32
#pragma comment(lib, "wsock32.lib")
#include <winsock.h>
#include <windows.h>
#define sleep Sleep
#endif
#ifdef MAC // or something
#define SOCKET_ERROR (-1)
#define closesocket close
typedef unsigned int SOCKET
// insert mac includes here <------------------------
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned long u32;
typedef unsigned short u16;
typedef unsigned char u8;
#define PORT_NUMBER 6559
#define MAX_PACKET_SIZE (1024+12)
#define MAX_DATA_SIZE (MAX_PACKET_SIZE - sizeof(Packet))
#define MAX_CONNECTIONS 16
struct Packet
{
u32 length, checksum, packet_id;
u16 type;
u8 flags, user_id;
u32 size() const
{
return length + sizeof(Packet);
}
inline void gen_checksum()
{
// TODO:crc32 please
}
inline bool chk_checksum()
{
// TODO:crc32 please
return true;
}
void swap_base()
{
//checksum = swap32(checksum);
//packet_id = swap32(packet_id);
//type = swap16(type);
}
};
struct Endpoint
{
int in_use;
sockaddr_in addr;
void init(char* adress = 0)
{
if(adress)
{
addr.sin_family = AF_INET;
addr.sin_port = PORT_NUMBER;
addr.sin_addr.s_addr = inet_addr(adress);
if(addr.sin_addr.s_addr == INADDR_NONE)
{
if(hostent* host = gethostbyname(adress))
{
memcpy(&addr.sin_addr, host->h_addr_list[0], host->h_length);
in_use = true;
}
}
else
{
in_use = true;
}
}
else
{
in_use = false;
}
}
bool send_packet(SOCKET s, Packet* p)
{
return sendto(s, ((char*)p)+4, p->size(), 0, (sockaddr*)&addr, sizeof(addr)) != SOCKET_ERROR;
}
};
struct PacketHandler
{
virtual void handle_packet(Packet* p){}
};
class ConnectionManager
{
private:
SOCKET s;
fd_set read;
Packet* packet_buffer;
Endpoint endpoints[MAX_CONNECTIONS];
public:
inline ConnectionManager()
{
s = 0;
#ifdef WIN32
WSADATA wsda;
WSAStartup(MAKEWORD(1,1), &wsda);
#endif
packet_buffer = (Packet*) new char[MAX_PACKET_SIZE];
for(int i = 0; i < MAX_CONNECTIONS; ++i)
{
endpoints[i].init();
}
}
bool open(int port, bool bind_local = true)
{
close();
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = port;
addr.sin_addr.s_addr = INADDR_ANY;
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(s)
{
if(bind_local && (bind(s, (sockaddr*)&addr, sizeof(addr)) != 0))
{
close();
return false;
}
return true;
}
return false;
}
inline void close()
{
if(s)
{
closesocket(s);
}
}
inline ~ConnectionManager()
{
delete [] ((char*)packet_buffer);
#ifdef WIN32
WSACleanup();
#endif
close();
}
inline void new_connection(char* adress, int client_number)
{
endpoints[client_number].init(adress);
}
inline void delete_connection(int client)
{
endpoints[client].init();
}
inline void send(Packet* p, int client)
{
endpoints[client].send_packet(s, p);
}
void process(PacketHandler* p)
{
FD_ZERO(&read);
FD_SET(s, &read);
const timeval nowait = {0, 0};
while(select(1, &read, 0, 0, &nowait))
{
FD_ZERO(&read);
FD_SET(s, &read);
int length = recvfrom(s, ((char*)packet_buffer)+4, MAX_PACKET_SIZE, 0, 0, 0);
packet_buffer->length = length - sizeof(Packet);
if(length >= sizeof(Packet) && packet_buffer->chk_checksum())
p->handle_packet(packet_buffer);
}
}
};
class Network : PacketHandler
{
public:
ConnectionManager* net;
inline Network()
{
net = new ConnectionManager;
}
inline ~Network()
{
delete net;
}
inline void process()
{
net->process(this);
}
inline bool open(int port, bool bind = true)
{
return net->open(port, bind);
}
};
#endif
packets.h
#ifndef __PACKETS_H__
#define __PACKETS_H__
enum
{
TEXT_PACKET,
};
struct TextPacket : Packet
{
char message[MAX_DATA_SIZE];
inline TextPacket() {}
inline TextPacket(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
set(fmt, args);
}
void set(const char* fmt, va_list args)
{
type = TEXT_PACKET;
length = _vsnprintf(message, sizeof(message), fmt, args);
}
};
#endif
sender.cpp
#include "udp.h"
#include "packets.h"
class Sender : public Network
{
public:
void open_connection(char* ip)
{
net->new_connection(ip, 0);
}
void send_message(char* fmt, ...)
{
va_list args;
va_start(args, fmt);
TextPacket the_text;
the_text.set(fmt, args);
net->send(&the_text, 0);
}
};
int main(int argc, int** argv)
{
Sender s;
if(s.open(0, false))
{
// if this is a remote computer running osX, it doesn''t seem to work
s.open_connection("localhost");
int i = 0;
for(;;)
{
s.send_message("Hello! + %d\n", i++);
sleep(1000);
}
}
}
receiver.cpp
#include "udp.h"
#include "packets.h"
class Receiver : public Network
{
void handle_packet(Packet* p)
{
switch(p->type)
{
case TEXT_PACKET:
printf(((TextPacket*)p)->message);
break;
}
}
};
int main(int argc, int** argv)
{
Receiver r;
if(r.open(PORT_NUMBER))
{
for(;;)
{
r.process();
sleep(1);
}
}
}
I realize that''s a lot of source to look over(about 250 lines)
I really do appreciate your time and I assure you I spent a lot of my own trying to find the problem myself.
Thanks in advance for any help!
-Melekor