Jump to content

UDP erro a mandar via internet


pikax
 Share

Recommended Posts

Boas, estou a trabalhar no meu projecto de PAP e tenho que fazer a parte da comunicação via UDP, já tá o servidor a funcionar e o cliente, só que só funciona para IP local e IP LAN, para o IP externo não funciona  :angry1: já desactivei a firewall, já tenho o DMZ ligado para o meu pc, mas mesmo assim não está a funcionar.

Quero fazer um código portável, só que este só está a funcionar para windows, ainda tenho que ajeitar a parte para linux

#include <iostream>
#include <list>
#include <WinSock2.h>
#include <Ws2tcpip.h>
#include "../defines.h"
#include "../cError.h"
#include "../net/cThread.h"
using namespace std;



#pragma comment(lib, "Ws2_32.lib")

class cPacket
{
public:
cPacket();
~cPacket();
cPacket(char* message):m_message(message){}

char* GetMessage()
{
	return m_message;
}

private:
char* m_message;
};

class cNetwork: public cThread
{
public:
cNetwork();
~cNetwork();

void Startup(U16 localListenPort,U16 foreignListenPort);
void Cleanup();
void Connect(char* IP);

void StartServer();
void StartClient();
void StartSending();
void StartListening();

void StopServer();
void StopClient();
void StopSending();
void StopListening();

void SendMessage();
void SendMessageTo(char* IP);

void ProcessMessage();

virtual L32	ThreadProc();

private:
inline void InitWSA();
inline void InitSocket(SOCKET &sock);
protected:
SOCKET	m_listenSocket;
SOCKET	m_sendSocket;
U16		m_localListenPort;
U16		m_foreignListenPort;

BOOL	m_bStarted;
BOOL	m_bListening;
BOOL	m_bSending;
U32		m_bytesTransfered;
};

cNetwork::cNetwork()
{
m_bSending		=false;
m_bListening	=false;
m_bStarted		=false;
}

cNetwork::~cNetwork()
{
Cleanup();
}

void cNetwork::Startup(U16 localListenPort,U16 foreignListenPort)
{
Cleanup();

InitWSA();

m_localListenPort	=localListenPort;
m_foreignListenPort	=foreignListenPort;
m_bytesTransfered	=0;
m_bStarted			=true;


}

void cNetwork::Cleanup()
{
if(!m_bStarted)
	return;

m_bStarted=false;
StopListening();
StopSending();

//limpar dados que faltam
#ifdef PLATFORM == PLATFORM_WINDOWS
WSACleanup();
#endif
}

/*Initialize WSAData for windows*/
inline void cNetwork::InitWSA()
{
#ifdef PLATFORM == PLATFORM_WINDOWS
WSAData wsaData;
int		error;

error=WSAStartup(MAKEWORD(2,2),&wsaData);
if(error== SOCKET_ERROR)
{
	char errorBuffer[100];

	error=WSAGetLastError();

	if(error==WSAVERNOTSUPPORTED)
	{
		sprintf_s(errorBuffer,"cNetwork::Startuo() - WSAStartup() error.\
							  \nRequested v2.2, found only v%d.%d", LOBYTE(wsaData.wVersion),HIBYTE(wsaData.wVersion));
		WSACleanup();
	}
	else
	{
		sprintf_s(errorBuffer,"cNetwork::Startup() - WSAStartup() error %d",WSAGetLastError());
	}
}
#endif // PLATFORM == PLATFORM_WINDOWS

return;
}

void cNetwork::Connect(char* IP)
{

}

void cNetwork::StartServer()
{

}

void cNetwork::StartClient()
{

}

void cNetwork::StartSending()
{
if(m_bSending || !m_bStarted)
{
	cout<<"retornou o startsending"<<endl;
	return;
}

m_bSending=true;

//possivelmente mudar para IPv6
m_sendSocket=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if (m_sendSocket==INVALID_SOCKET)
{
	//throw error
	cout<<"errorr"<<endl;
	return;
}

#if PLATFORM == PLATFORM_MAC || PLATFORM == PLATFORM_UNIX

int nonBlocking = 1;
if ( fcntl( m_sendSocket, F_SETFL, O_NONBLOCK, nonBlocking ) == -1 )
{
	printf( "failed to set non-blocking socket\n" );
	return ;
}

#elif PLATFORM == PLATFORM_WINDOWS

DWORD nonBlocking = 1;
if ( ioctlsocket( m_sendSocket, FIONBIO, &nonBlocking ) != 0 )
{
	printf( "failed to set non-blocking socket\n" );
	return ;
}

#endif
/*
//possivelmente mudar para IPv6
SOCKADDR_IN	localAddr;
int			result;

memset(&localAddr,0,sizeof(SOCKADDR_IN));
localAddr.sin_family	=	AF_INET;
localAddr.sin_addr.s_addr=	htonl(INADDR_ANY);
localAddr.sin_port		=	htons(m_foreignListenPort);

//result= bind(m_sendSocket,(sockaddr*)&localAddr,sizeof(SOCKADDR_IN));

if(result==SOCKET_ERROR)
{
	closesocket(m_listenSocket);
	//throw error
	cout<<"sock error m_sendsocket"<<endl;
}*/
}

void cNetwork::StartListening()
{
if(m_bListening || !m_bStarted)
{
	cout<<"saiu no startlistening()"<<endl;
	return;
}

m_bListening=true;

//possivelmente mudar para IPv6
m_listenSocket=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if (m_listenSocket==INVALID_SOCKET)
{
	cout<<"saiu no startlistening() 2"<<endl;
	//throw error
	return;
}

//possivelmente mudar para IPv6
SOCKADDR_IN	localAddr;
int			result;

memset((char*)&localAddr,0,sizeof(localAddr));
localAddr.sin_family	=	AF_INET;
localAddr.sin_addr.s_addr=	htonl(INADDR_ANY);
localAddr.sin_port		=	htons(m_localListenPort);

result= bind(m_listenSocket,(sockaddr*)&localAddr,sizeof(localAddr));

if(result==SOCKET_ERROR)
{
	closesocket(m_listenSocket);
	//throw error
	cout<<"sock error m_listensocket"<<endl;
}

#if PLATFORM == PLATFORM_MAC || PLATFORM == PLATFORM_UNIX

int nonBlocking = 1;
if ( fcntl( m_listenSocket, F_SETFL, O_NONBLOCK, nonBlocking ) == -1 )
{
	printf( "failed to set non-blocking socket\n" );
	return ;
}

#elif PLATFORM == PLATFORM_WINDOWS

DWORD nonBlocking = 1;
if ( ioctlsocket( m_listenSocket, FIONBIO, &nonBlocking ) != 0 )
{
	printf( "failed to set non-blocking socket\n" );
	return ;
}

#endif

cThread::Begin();
}

void cNetwork::StopServer()
{

}

void cNetwork::StopClient()
{

}

void cNetwork::StopSending()
{

}

void cNetwork::StopListening()
{

}


void cNetwork::SendMessage()
{

}

void cNetwork::SendMessageTo(char* IP)
{
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(IP);
address.sin_port = htons(m_foreignListenPort);
cout<<"\nPORT="<< htons(m_foreignListenPort)<<endl;

struct sockaddr_in from;
int fromLength = sizeof( from );

char buffer[256];

cout<<"escreva a sua sms:";
//cin>>buffer;
sprintf_s(buffer,"MENSAGEM RECEBIDA!!");
sendto(m_sendSocket,buffer,256,0,(const struct sockaddr*)&address,sizeof(address));
}

L32 cNetwork::ThreadProc()
{
cout<<"Thread a funcar\n";

timeval	waitTimeSrc;
U16		result;
FD_SET	set;
	InitWSA();
//this->Startup(m_localListenPort,m_foreignListenPort);
while ( 1 )
{

	char packet_data[256];
	unsigned int maximum_packet_size = sizeof( packet_data );

	FD_ZERO(&set);
	FD_SET(m_listenSocket,&set);

	waitTimeSrc.tv_sec=0;
	waitTimeSrc.tv_usec=0;

	struct sockaddr_in from;
	int fromLength = sizeof( from );

	result=select(FD_SETSIZE,&set,NULL,NULL,&waitTimeSrc);
	if (result==0)
	{
		continue;
	}

	if(result==SOCKET_ERROR)
	{
		cout<<"ERROR select"<<endl;
		cin.get();
	}



	int received_bytes = recvfrom( m_listenSocket, packet_data, 256,0, (struct sockaddr*)&from, &fromLength );


	if ( received_bytes == SOCKET_ERROR )
	{
		//printf("error no receive");
		//printf("LOLADA\n");
		//getchar();
		//getchar();
		//cin>>fromLength;
		continue;
	}


	unsigned int from_address = ntohl( from.sin_addr.s_addr );
	unsigned int from_port = ntohs( from.sin_port );

	// process received packet
	printf("do endereço: %s - com %d bytes\n",inet_ntoa(from.sin_addr),fromLength);
	printf("recebida:%s\n",packet_data);



}
cout<<"thread foi à vida"<<endl;
return 1;
}

/*asdkljhyasdkjhasdjklasd*/
void cNetwork::ProcessMessage()
{

}

int main()
{
cNetwork network;
int op;


cout<<"Server(1) ou Cliente(0)"<<endl;
cin>>op;
if(op)
{
	network.Startup(27016,27015);
	network.StartListening();
	//network.Begin();
	//network.ThreadProc();
}
else
{
	network.Startup(27015,27016);
	network.StartSending();

	while(1)
	{
		Sleep(500);
		network.SendMessageTo("127.0.0.1");
		Sleep(500);
		network.SendMessageTo("95.92.242.124");
		Sleep(500);
		network.SendMessageTo("192.168.1.69");
	}
}
/*
network.Startup(7000,7000);
network.StartSending();

while(1)
{
	network.SendMessageTo("95.92.242.124");
}*/
Sleep(30000);
}

O resto do código está no repositório da google

Ainda me falta criar os hosts, etc.

Já agora, tambem tenho dúvidas nas threads para linux e para macs, que não sei o que utilizar, para linux tou a utilizar o pthread só que acho que não está a funcionar, para macs infelizmente não posso programar nada, já que não tenho nenhum mac 🙂

Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Link to comment
Share on other sites

Eu queria mais fazer a PAP também para fim pedagógico, gostava de fazer as coisas +/- à mão, pelo o menos não usar coisas que eu não saiba implementar ou perceba como funciona(claro sem estar a falar de coisas muito low level, senão ia para raw sockets por exemplo 🙂 ), fazendo por mim, penso que aumento mais os meus conhecimentos e ganho mais experiência

Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Link to comment
Share on other sites

nesse caso terás o dobro do trabalho no ponto da portabilidade ....

o pthreads funciona em linux e no windows (pelo menos se usas o mingw, pois de VC++ náo conheço bem). Caso não exista uma implementação de pthreads para VC++ terás de usar as funções da win32 que te leva a mais um trabalho para correr nos vários sistemas operativos.

o uso das bibliotacas existêntes não é algo mau. muito pelo contrário, já diz o ditado : ninguém inventa a roda.

se não percebes como funciona, bem podes tentar por a funcionar as bibliotecas mas ficarás no por tentar, principalmente no que toca a sockets ...

um caso semelhante é o detectar o precionar uma tecla sem bloquear a aplicação. se perguntares aqui no forum como fazer, ninguém vai dizer para ires às funções do SO para o fazer, iram referenciar o ncurses ou algo semelhante ...

IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Por enquanto não estou com muita presa, por isso posso perder tempo a tratar da portabilidade.

eu no windows sei usar threads só em linux é que não consigo fazer, também é porque não uso muito linux.

Eu utilizo algumas bibliotecas, por exemplo std 🙂 entre mais algumas, o meu objectivo neste projecto era criar uma framework para eu trabalhar à vontade.

Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Link to comment
Share on other sites

Boas pikax, só por mera curiosidade, podes-me explicar em que consiste a tua PAP?

Num jogo 3D online

Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Link to comment
Share on other sites

E tu estas a programar o quê ao certo? xD

Como assim??

A minha para ser entregada no final de junho será um jogo online, nada de muito complicado só andar, matar alguma coisa e pouco mais(o que tiver tempo).

Graficos:

DirectX10 com Cg.

Network:

Servidor em linux a comunicar atraves de UDP

Base de Dados

MySQL

Script:

Lua

Fisica:

PhysX da nvidia

Não espero conseguir fazer algo de outro mundo, só estou a utilizar a PAP para ter um pretexto para estudar isto, ainda estou muito longe, por enquanto consigo comunicar com o servidor, base de dados e fazer rendering com o directX 10 e tambem fazer load de models feitos em blender, 3ds Max, desde que estejam em extenção OBJ consigo exportar para o jogo.

pelo o que os meus profs dizem, acham que é demasiado e que não irei conseguir acabar a tempo, como se diz:"vamos indo, vamos fazendo" 😕

só irei mudar o DirectX 10 para OpenGL.

Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.