예제 #1
0
void CUDPServer::sendAll(CUDPPacket poPacket)
{
	UDPsocket oSocket;
	int i, iResult;
	IPaddress *poIPAddress;
	
	oSocket=SDLNet_UDP_Open(0);
	if(!oSocket) 
	{
		printf("SDLNet_UDP_Open: %s\n", SDLNet_GetError());
	}	

	for ( i = 0 ; i < goClientManager.getNumberClients() ; i++ )
	{
		poIPAddress = goClientManager.getIPAddress(i);

		iResult = SDLNet_UDP_Bind( oSocket, -1, poIPAddress );
		if( iResult == -1 ) 
		{
			printf("SDLNet_UDP_Bind: %s\n", SDLNet_GetError());
			// do something because we failed to bind
		}
		poPacket.send(oSocket, MSG_TEXTMESSAGE);
		SDLNet_UDP_Unbind( oSocket, iResult );
	}	
	SDLNet_UDP_Close( oSocket );

}
예제 #2
0
int game_host::waitForClient_test()
{
	cout << "waiting for first player to connect...\n";
	while(!(player1sd = SDLNet_TCP_Accept(sd))) //wait for first connection, with 50ms delay to keep CPU down
		SDL_Delay(50);

	string ipMess = "";
	while(SDLNet_UDP_Recv(p1UDPsock, UDPpack1) == 0)
		SDL_Delay(5);
	SDLNet_UDP_Bind(p1UDPsock,10,&(UDPpack1->address));

	cout << this->recieveMessagep1() << "\n"; //on successful connect, client sends a message

	SDLNet_TCP_AddSocket(socketset, player1sd); //could error check here
	this->player1ip = SDLNet_TCP_GetPeerAddress(player1sd);
	//SDLNet_ResolveHost(&(UDPpack1->address), cl.c_str(), port);
	//player2ip->host = SDLNet_TCP_GetPeerAddress(player1sd)->host;
	//player2ip->port = port;

	//UDPpack1->address = *player1ip;

	sendtoP1_test("1SIG:START");
	cout << "client connected, continuing...\n";
	return 1;
}
예제 #3
0
static SINT8 NET_NetMakeNode(const char *hostname)
{
	INT32 newnode;
	char *portchar;
	UINT16 portnum = sock_port;
	IPaddress hostnameIP;

	// retrieve portnum from address!
	{
		char *localhostname = strdup(hostname);
		strtok(localhostname, ":");
		portchar = strtok(NULL, ":");
		if (portchar)
			portnum = atoi(portchar);
		free(localhostname);
	}

	if (SDLNet_ResolveHost(&hostnameIP,hostname,portnum) == -1)
	{
		CONS_Printf("SDL_Net: %s",SDLNet_GetError());
		return -1;
	}
	newnode = SDLNet_UDP_Bind(mysocket,-1,&hostnameIP);
	if (newnode == -1)
	{
		CONS_Printf("SDL_Net: %s",SDLNet_GetError());
		return newnode;
	}
	newnode++;
	M_Memcpy(&clientaddress[newnode],&hostnameIP,sizeof (IPaddress));
	return (SINT8)newnode;
}
예제 #4
0
int I_ConnectToServer(const char *serv)
{
  char server[500], *p;
  Uint16 port;

  /* Split serv into address and port */
  if (strlen(serv)>500) return 0;
  strcpy(server,serv);
  p = strchr(server, ':');
  if(p)
  {
    *p++ = '\0';
    port = atoi(p);
  }
  else
    port = 5030; /* Default server port */

  SDLNet_ResolveHost(&serverIP, server, port);
  if ( serverIP.host == INADDR_NONE )
    return -1;

  if (SDLNet_UDP_Bind(udp_socket, 0, &serverIP) == -1)
    return -1;

  return 0;
}
예제 #5
0
int I_ConnectToServer(const char *serv)
{
  char server[500], *p;
  u16 port;
  
  iprintf("enter\n");

  /* Split serv into address and port */
  if (strlen(serv)>500)
  {
  iprintf("ARGH!\n");
  return 0;
  }
  
  strcpy(server,serv);
  p = strchr(server, ':');
  if(p)
  {
    *p++ = '\0';
    port = atoi(p);
  }
  else
    port = 5030; // Default server port
	
iprintf("server: %s port: %d\n", server, port);

  SDLNet_ResolveHost(&serverIP, server, port);
  if ( serverIP.host == INADDR_NONE )
    return -1;

  if (SDLNet_UDP_Bind(udp_socket, 0, &serverIP) == -1)
    return -1;

  return 0;
}
예제 #6
0
int network_udp_bind(UDPsocket udp, int channel, IPaddress* ipa) {
        network_udp_reopen(udp, 0);
        int c = SDLNet_UDP_Bind(udp, channel, ipa);
        if (c == -1) {
                std::cerr << "Failed to bind UDP on channel " << channel << ": " << SDLNet_GetError() << "\n";
        }
        return c;
}
예제 #7
0
/*
* network_udp_bind() - Bind the given socket to the given IP address data using the given channel
* @udp: the socket to bind
* @channel: the channel to use, set it to -1 in order to use the first available channel
* @ipa: the IP address data
*/
int network_udp_bind(UDPsocket* udp, int channel, IPaddress* ipa) {
	network_udp_reopen(udp, network_get_port(ipa->port)); // Reset the socket in case it was previously bound

	int c = SDLNet_UDP_Bind(*udp, channel, ipa); // Attempt to bind the socket to the given IP address
	if (c == -1) { // If the socket failed to bind
		std::cerr << "Failed to bind UDP on channel " << channel << ": " << SDLNet_GetError() << "\n"; // Output the error message
	}

	return c; // Return the channel on success, or -1 on failure
}
예제 #8
0
int game_host::waitForClients()
{
	cout << "waiting for first player to connect...\n";
	while(!(player1sd = SDLNet_TCP_Accept(sd))) //wait for first connection, with 50ms delay to keep CPU down
		SDL_Delay(50);
	string ipMess = "";
	while(SDLNet_UDP_Recv(p1UDPsock, UDPpack1) == 0)
		SDL_Delay(5);
	SDLNet_UDP_Bind(p1UDPsock,10,&(UDPpack1->address));
	cout << this->recieveMessagep1() << "\n"; //client sends its IP

	SDLNet_TCP_AddSocket(socketset, player1sd); //could error check here
	this->player1ip = SDLNet_TCP_GetPeerAddress(player1sd);
	//UDPpack1->address.port = player1ip.port;
	//UDPpack1->address.host = player1ip.host;
	cout << "waiting for second player to connect...\n";
	while(!(player2sd = SDLNet_TCP_Accept(sd)))
		SDL_Delay(50);
	while(!SDLNet_UDP_Recv(p1UDPsock, UDPpack2))
		SDL_Delay(5);
	SDLNet_UDP_Bind(p1UDPsock,10,&(UDPpack2->address));
	//cout << this->recieveMessagep2() << "\n";
	SDLNet_TCP_AddSocket(socketset, player2sd); //could error check here as well
	player2ip = SDLNet_TCP_GetPeerAddress(player2sd);
	//UDPpack2->address.port = player2ip.port;
	//UDPpack2->address.host = player2ip.host;

	if(SDLNet_TCP_Send(player1sd, "1SIG:START", 16 /* buff.length()+1*/) < 16)
	{
		cout << "Message to client 1 failed to send...\n";
		return -1;
	}
	if(SDLNet_TCP_Send(player2sd, "2SIG:START", 16 /*buff.length()+1*/) < 16)
	{
		cout << "Message to client 2 failed to send...\n";
		return -1;
	}

	cout << "both clients connected, continuing...\n";
	return 1;
}
예제 #9
0
static void NET_Get(void)
{
	INT32 mystatus;
	INT32 newnode;
	mypacket.len = MAXPACKETLENGTH;
	if (!NET_CanGet())
	{
		doomcom->remotenode = -1; // no packet
		return;
	}
	mystatus = SDLNet_UDP_Recv(mysocket,&mypacket);
	if (mystatus != -1)
	{
		if (mypacket.channel != -1)
		{
			doomcom->remotenode = mypacket.channel+1; // good packet from a game player
			doomcom->datalength = mypacket.len;
			return;
		}
		newnode = SDLNet_UDP_Bind(mysocket,-1,&mypacket.address);
		if (newnode != -1)
		{
			size_t i;
			newnode++;
			M_Memcpy(&clientaddress[newnode], &mypacket.address, sizeof (IPaddress));
			DEBFILE(va("New node detected: node:%d address:%s\n", newnode,
					NET_GetNodeAddress(newnode)));
			doomcom->remotenode = newnode; // good packet from a game player
			doomcom->datalength = mypacket.len;
			for (i = 0; i < numbans; i++)
			{
				if (NET_cmpaddr(&mypacket.address, &banned[i]))
				{
					DEBFILE("This dude has been banned\n");
					NET_bannednode[newnode] = true;
					break;
				}
			}
			if (i == numbans)
				NET_bannednode[newnode] = false;
			return;
		}
		else
			CONS_Printf("SDL_Net: %s",SDLNet_GetError());
	}
	else if (mystatus == -1)
	{
		CONS_Printf("SDL_Net: %s",SDLNet_GetError());
	}

	DEBFILE("New node detected: No more free slots\n");
	doomcom->remotenode = -1; // no packet
}
예제 #10
0
파일: net.cpp 프로젝트: Timo6/trackeditor
bool NET::Connect(string host, int port)
{
	server = false;
	bool err = false;
	
	if (host == "Server")
		server = true;
	
	if (remote_socket != NULL)
	{
		SDLNet_UDP_Close(remote_socket);
		remote_socket = NULL;
	}
	
	if (server)
		remote_socket = SDLNet_UDP_Open(port);
	else
		remote_socket = SDLNet_UDP_Open(0);
	
	if (!server)
	{
		SDLNet_ResolveHost(&remote_ip, host.c_str(), port);
		
		SDLNet_UDP_Unbind(remote_socket, 0);
		if (SDLNet_UDP_Bind(remote_socket, 0, &remote_ip)==-1)
		{
			err = true;
			
			if (NET_DEBUG)
			{
				cout << "net:  couldn't bind UDP socket to host " << host << " port " << port << endl;
				printf("SDLNet_UDP_Bind: %s\n",SDLNet_GetError());
			}
		}
	}
	
	//try a handshake
	if (pout == NULL)
		pout = SDLNet_AllocPacket(MAX_PACKET_SIZE);
	if (pin == NULL)
		pin = SDLNet_AllocPacket(MAX_PACKET_SIZE);

	if (server)
	{
	}
	else
	{
		err = ClientHandshake();
	}
	
	return !err;
}
예제 #11
0
cearth_ctx *
cearthctx_new(void)
{
        cearth_ctx *ctx = calloc(1, sizeof(cearth_ctx));
        /* Connect to server. */
        ctx->sk = SDLNet_UDP_Open(0);

        IPaddress ip;
        SDLNet_ResolveHost(&ip, haven_serv, HAVENSERV_PORT);

        int success = SDLNet_UDP_Bind(ctx->sk, -1, &ip);
        /* TEST */
        printf("Success: %d\n", success);
        return ctx;
}
예제 #12
0
static UDPsocket NET_Socket(void)
{
	UDPsocket temp = NULL;
	Uint16 portnum = 0;
	IPaddress tempip = {INADDR_BROADCAST,0};
	//Hurdler: I'd like to put a server and a client on the same computer
	//Logan: Me too
	//BP: in fact for client we can use any free port we want i have read
	//    in some doc that connect in udp can do it for us...
	//Alam: where?
	if (M_CheckParm("-clientport"))
	{
		if (!M_IsNextParm())
			I_Error("syntax: -clientport <portnum>");
		portnum = atoi(M_GetNextParm());
	}
	else
		portnum = sock_port;
	temp = SDLNet_UDP_Open(portnum);
	if (!temp)
	{
			CONS_Printf("SDL_Net: %s",SDLNet_GetError());
		return NULL;
	}
	if (SDLNet_UDP_Bind(temp,BROADCASTADDR-1,&tempip) == -1)
	{
		CONS_Printf("SDL_Net: %s",SDLNet_GetError());
		SDLNet_UDP_Close(temp);
		return NULL;
	}
	clientaddress[BROADCASTADDR].port = sock_port;
	clientaddress[BROADCASTADDR].host = INADDR_BROADCAST;

	doomcom->extratics = 1; // internet is very high ping

	return temp;
}
예제 #13
0
파일: net.cpp 프로젝트: Timo6/trackeditor
//this function assumes pin already has an incoming packet from the client
bool NET::ServerHandshake()
{
	string handshake = HANDSHAKESTR;
	string handshake_reply = HANDSHAKEREPLYSTR;
//	int timeout = HANDSHAKETIMEOUT;
	
	bool err = false;
	
	if (IsEqualToPacket(pin, CONTROL_HANDSHAKE, (void *) handshake.c_str(), handshake.length()))
	{
		SDLNet_UDP_Unbind(remote_socket, 0);
		if (SDLNet_UDP_Bind(remote_socket, 0, &(pin->address))==-1)
		{
			err = true;
			
			if (NET_DEBUG)
			{
				cout << "net:  couldn't bind UDP socket to host " << SDLNet_ResolveIP(&(pin->address)) << endl;
				printf("SDLNet_UDP_Bind: %s\n",SDLNet_GetError());
			}
		}
		WriteToPacket(pout, CONTROL_HANDSHAKE, (void *) handshake_reply.c_str(), handshake_reply.length());
		UDPSend(pout, 0);
		connected = true;
		if (NET_DEBUG)
			cout << "net:  incoming connection established" << endl;
	}
	else 
	{
		if (NET_DEBUG)
			cout << "net:  Invalid handshake from " << SDLNet_ResolveIP(&(pin->address)) << endl;
		err = true;
	}
	
	return err;
}
예제 #14
0
/**
 * @brief Adds remote peer or finds via DNS
 * 
 * @param address Address to add
 * @param port Port to connect to
 * @param outport Port to connect on
 * @return 0 on fail, 1 on success, 2 if already bound
 */
int Peer::AddRemotePeer(const std::string address, const int port, const int outport)
{
	IPaddress ip;
	ip.port = port;
	
	Print("resolving host...\n");
	if (SDLNet_ResolveHost(&ip, address.c_str(), 0)==-1)
	{
		Print("Some DNS requests require more then one request before you will get a response!\n");
		return 0;
	}
	Print("found dns match: %s\n", getIP(ip.host));
	Print("checking for avaliable sockets...\n");
	//Do we have any sockets?
	if (sockets.size()) 
	{
		//if no, add one
		if (!addSocket(outport))
		{
			//if we failed to add one, return
			return 0;
		}
	}

	// try and see if this peer already has a socket / channel bound
	Print("crosschecking with current peers...\n");
	auto gp = GetRemotePeer(&ip);
	if (std::get<0>(gp)!=-1 && std::get<1>(gp)!=-1)
	{
		return 2; // if already bound then return 2
	}

	Print("finding an empty socket channel...\n");
	//TODO: write a function that finds an empty socket/channel maybe
	// find an empty channel to bind the peer to
	for (UDPsocket &sock : sockets)
	{
		if (outport) // if we want a specific outport
		{
			// and the socket we are checking is not our desired port
			Uint16 port = SDLNet_UDP_GetPeerAddress(sock,-1)->port;
			if (SDLNet_Read16(&port) != outport)
				continue; // skip this iteration
		}

		for ( int i = 0; i < (SDLNET_MAX_UDPADDRESSES-1); i++)
		{
			IPaddress *peer = SDLNet_UDP_GetPeerAddress(sock,i);
			if (!peer)
			{
				Print("Found an empty sock / channel\n");
				int channel = SDLNet_UDP_Bind(sock, i, &ip);
				if (channel == -1)
				{
					Print("SDLNet_UDP_Bind: %s\n", SDLNet_GetError());
					return 0; // Failed to bind
				}
				else
				{
					Print("BOUND\n");
					return 1; // Bound!
				}
			}
		}
	}

	Print("none found, adding a new socket and trying again...\n");
	// if no empty channel found, add socket and try again

	if (!addSocket(outport))
	{
		//if we failed to add one, return
		return 0;
	}

	for (UDPsocket &sock : sockets)
	{
		if (outport) // if we want a specific outport
		{
			// and the socket we are checking is not our desired port
			Uint16 port = SDLNet_UDP_GetPeerAddress(sock,-1)->port;
			if (SDLNet_Read16(&port) != outport){
				continue; // skip this iteration
			}
		}

		for ( int i = 0; i < (SDLNET_MAX_UDPADDRESSES-1); i++)
		{
			IPaddress *peer = SDLNet_UDP_GetPeerAddress(sock, i);
			if (!peer)
			{
				Print("Found an empty sock / channel\n");
				
				int channel = SDLNet_UDP_Bind(sock, i, &ip);
				if (channel == -1)
				{
					Print("SDLNet_UDP_Bind: %s\n", SDLNet_GetError());
					return 0; // Failed to bind
				}
				else
				{
					Print("BOUND\n");
					return 1; // Bound!
				}
			}
		}
	}
	Print("did not bind.\n");
	return 0;
	//for (IPaddress & ip : SDLNet_UDP_GetPeerAddress(,-1))
}
예제 #15
0
int FCEUD_NetworkConnect(void)
{
 IPaddress rip;

 SDLNet_Init();
 int netplay =1;
 if(netplay==1)	/* Be a server. */
 {
  TCPsocket tmp;
  Uint16 p=LocalPortUDP;

  SDLNet_ResolveHost(&rip,NULL,LocalPortTCP);

  UDPSocket=SDLNet_UDP_Open(p);

  tmp=SDLNet_TCP_Open(&rip);
  Socket=SDLNet_TCP_Accept(tmp);

  memcpy(&rip,SDLNet_TCP_GetPeerAddress(Socket),sizeof(IPaddress));
  {
   Uint32 buf[12];
   uint32 player=1;

   magic=SDL_GetTicks();

   SDLNet_Write32(buf,uport);
   SDLNet_Write32(buf+4,1);
   SDLNet_Write32(buf+8,magic);

   SDLNet_TCP_Send(Socket, buf, 12);

   /* Get the UDP port the client is waiting for data on. */
   SDLNet_TCP_Recv(Socket, buf, 2);
   RemotePortUDP=de32(buf);
  }
 }
 else		/* Be a client	*/
 {
  SDLNet_ResolveHost(&rip,ServerHost,RemotePortTCP);
  Socket=SDLNet_TCP_Open(&rip);

  {
   Uint16 p=LocalPortUDP;
   uint8 buf[12];
  
   UDPSocket=SDLNet_UDP_Open(p);

   /* Now, tell the server what local UDP port it should send to. */
   en32(buf,p);
   SDLNet_TCP_Send(Socket, buf, 4);
 
   /* Get the UDP port from the server we should send data to. */
   SDLNet_TCP_Recv(Socket, buf, 12);
   RemotePortUDP=de32(buf);
   magic=de32(buf+8);
  }
  set=SDLNet_AllocSocketSet(1);
  SDLNet_TCP_AddSocket(set,Socket);
  SDLNet_UDP_AddSocket(set,UDPSocket);
 }	// End client connect code.

 rip.port=RemotePortUDP;
 SDLNet_UDP_Bind(UDPSocket, 0, &rip);
}
예제 #16
0
// attempt to punch through firewall by firing off UDP packets at the opponent
// exchange game information
int network_connect( void )
{
#ifdef __BLACKBERRY__
#else
	SDLNet_ResolveHost(&ip, network_opponent_host, network_opponent_port);

	SDLNet_UDP_Bind(socket, 0, &ip);

	Uint16 episodes = 0, episodes_local = 0;
	assert(EPISODE_MAX <= 16);
	for (int i = EPISODE_MAX - 1; i >= 0; i--)
	{
		episodes <<= 1;
		episodes |= (episodeAvail[i] != 0);
	}
	episodes_local = episodes;

	assert(NET_PACKET_SIZE - 12 >= 20 + 1);
	if (strlen(network_player_name) > 20)
		network_player_name[20] = '\0';

connect_reset:
	network_prepare(PACKET_CONNECT);
	SDLNet_Write16(NET_VERSION, &packet_out_temp->data[4]);
	SDLNet_Write16(network_delay,   &packet_out_temp->data[6]);
	SDLNet_Write16(episodes_local,  &packet_out_temp->data[8]);
	SDLNet_Write16(thisPlayerNum,   &packet_out_temp->data[10]);
	strcpy((char *)&packet_out_temp->data[12], network_player_name);
	network_send(12 + strlen(network_player_name) + 1); // PACKET_CONNECT

	// until opponent sends connect packet
	while (true)
	{
		push_joysticks_as_keyboard();
		service_SDL_events(false);

		if (newkey && lastkey_sym == SDLK_ESCAPE)
			network_tyrian_halt(0, false);

		// never timeout
		last_in_tick = SDL_GetTicks();

		if (packet_in[0] && SDLNet_Read16(&packet_in[0]->data[0]) == PACKET_CONNECT)
			break;

		network_update();
		network_check();

		SDL_Delay(16);
	}

connect_again:
	if (SDLNet_Read16(&packet_in[0]->data[4]) != NET_VERSION)
	{
		fprintf(stderr, "error: network version did not match opponent's\n");
		network_tyrian_halt(4, true);
	}
	if (SDLNet_Read16(&packet_in[0]->data[6]) != network_delay)
	{
		fprintf(stderr, "error: network delay did not match opponent's\n");
		network_tyrian_halt(5, true);
	}
	if (SDLNet_Read16(&packet_in[0]->data[10]) == thisPlayerNum)
	{
		fprintf(stderr, "error: player number conflicts with opponent's\n");
		network_tyrian_halt(6, true);
	}

	episodes = SDLNet_Read16(&packet_in[0]->data[8]);
	for (int i = 0; i < EPISODE_MAX; i++) {
		episodeAvail[i] &= (episodes & 1);
		episodes >>= 1;
	}

	network_opponent_name = malloc(packet_in[0]->len - 12 + 1);
	strcpy(network_opponent_name, (char *)&packet_in[0]->data[12]);

	network_update();

	// until opponent has acknowledged
	while (!network_is_sync())
	{
		service_SDL_events(false);

		// got a duplicate packet; process it again (but why?)
		if (packet_in[0] && SDLNet_Read16(&packet_in[0]->data[0]) == PACKET_CONNECT)
			goto connect_again;

		network_check();

		// maybe opponent didn't get our packet
		if (SDL_GetTicks() - last_out_tick > NET_RETRY)
			goto connect_reset;

		SDL_Delay(16);
	}

	// send another packet since sometimes the network syncs without both connect packets exchanged
	// there should be a better way to handle this
	network_prepare(PACKET_CONNECT);
	SDLNet_Write16(NET_VERSION, &packet_out_temp->data[4]);
	SDLNet_Write16(network_delay,   &packet_out_temp->data[6]);
	SDLNet_Write16(episodes_local,  &packet_out_temp->data[8]);
	SDLNet_Write16(thisPlayerNum,   &packet_out_temp->data[10]);
	strcpy((char *)&packet_out_temp->data[12], network_player_name);
	network_send(12 + strlen(network_player_name) + 1); // PACKET_CONNECT

	connected = true;
#endif

	return 0;
}
예제 #17
0
int main(int argc, char **argv)
{
	Uint16 port;
	char *host,*fname,*fbasename;
	Sint32 flen,pos,p2;
	int len,blocks,i,err=0;
	Uint32 ack;
	IPaddress ip;
	UDPsocket sock;
	UDPpacket *in, *out;
	FILE *f;
	
	/* check our commandline */
	if(argc<4)
	{
		printf("%s host port file\n",argv[0]);
		exit(0);
	}
	
	/* initialize SDL */
	if(SDL_Init(0)==-1)
	{
		printf("SDL_Init: %s\n",SDL_GetError());
		exit(1);
	}

	/* initialize SDL_net */
	if(SDLNet_Init()==-1)
	{
		printf("SDLNet_Init: %s\n",SDLNet_GetError());
		exit(2);
	}

	/* get the host from the commandline */
	host=argv[1];
	/* get the port from the commandline */
	port=(Uint16) strtol(argv[2],NULL,0);
	if(!port)
	{
		printf("a server port cannot be 0.\n");
		exit(3);
	}
	/* get filename to get from server from commandline */
	fname=argv[3];

	if(SDLNet_ResolveHost(&ip,host,port)==-1)
	{
		printf("SDLNet_ResolveHost: %s\n",SDLNet_GetError());
		exit(4);
	}
	
	/* open udp client socket */
	if(!(sock=SDLNet_UDP_Open(0)))
	{
		printf("SDLNet_UDP_Open: %s\n",SDLNet_GetError());
		exit(5);
	}

	/* allocate max packet */
	if(!(out=SDLNet_AllocPacket(65535)))
	{
		printf("SDLNet_AllocPacket: %s\n",SDLNet_GetError());
		exit(6);
	}
	if(!(in=SDLNet_AllocPacket(65535)))
	{
		printf("SDLNet_AllocPacket: %s\n",SDLNet_GetError());
		exit(6);
	}
	
	/* bind server address to channel 0 */
	if(SDLNet_UDP_Bind(sock, 0, &ip)==-1)
	{
		printf("SDLNet_UDP_Bind: %s\n",SDLNet_GetError());
		exit(7);
	}

	/* open output file */
	fbasename=strrchr(fname,'/');
	if(!fbasename)
		fbasename=fname;
	else
		fbasename++;
	printf("writting file: %s\n",fbasename);
	if(!(f=fopen(fbasename,"wb")))
	{
		perror("fopen");
		exit(8);
	}

	/* request file / expect filesize */
	printf("requesting file=%s\n",fname);
	out->data[0]=1<<4;
	strcpy((char*)out->data+1,fname);
	out->len=strlen(fname)+2;
	if(udpsend(sock,0,out,in,200,1,TIMEOUT)<1)
		exit(9);
	
	flen=SDLNet_Read32(in->data+1);
	len=SDLNet_Read32(in->data+5);
	blocks=(flen+len-1)/len;
	printf("flen=%d blocksize=%d blocks=%d\n",flen,len,blocks);

	/* send ready / expect file */
	printf("starting transfer\n");
	out->data[0]=2<<4;
	out->len=1;
	if(udpsend(sock,0,out,in,10,2,TIMEOUT)<1)
		exit(10);
	
	if(flen<0)
	{
		printf("file not available...\n");
		exit(11);
	}

	pos=0; /* count per 32 blocks */
	while(pos*32<blocks && !err)
	{
		/*printf("pos=%d\n",pos); */
		ack=0;
		if((pos+1)*32>=blocks)
		{
			for(i=blocks%32;i<32;i++)
				ack|=1<<i;
		}
		printf("\r                                                                  "
				"\r%3d%% %08x: ",(pos*3200)/blocks,pos*32*len);
		while(ack!=0xffffffff && !err)
		{
			i=in->data[1];
			p2=SDLNet_Read32(in->data+2);
			/*printf("received %d,%d\n",i,p2); */
			if(!(ack&1<<i) && p2>=pos*32*len)
			{
				fseek(f,p2,SEEK_SET);
				fwrite(in->data+6,in->len-6,1,f);
				ack|=1<<i;

				printf(".");
				fflush(stdout);
			}
			if(ack!=0xffffffff)
				err=udprecv(sock,in,10,2,500);
			if(err<0)
				continue; /* error... */
			if(!err)
			{
				/*printf("sending ack 0x%0X\n",ack); */
				out->data[0]=3<<4;
				SDLNet_Write32(pos*32*len,out->data+1);
				SDLNet_Write32(ack,out->data+5);
				out->len=9;
				SDLNet_UDP_Send(sock,0,out);
			}
			err=0;
		}
		pos++;
	}
	
	printf("\ndone.\n");

	fclose(f);
	
	/* close the socket */
	SDLNet_UDP_Close(sock);
	
	/* free packets */
	SDLNet_FreePacket(out);
	SDLNet_FreePacket(in);
	
	/* shutdown SDL_net */
	SDLNet_Quit();

	/* shutdown SDL */
	SDL_Quit();

	return(0);
}
예제 #18
0
int UDPNetwork::Bind(IPaddress add, int channel)
{
	const int ret = SDLNet_UDP_Bind(m_socket, channel, &add);
	if ( ret < 0 ) throw(std::runtime_error("Failed to bind to a channel"));
	return ret;
}
예제 #19
0
UDP_CHANNEL I_RegisterPlayer(IPaddress *ipaddr)
{
  static int freechannel;
  return(SDLNet_UDP_Bind(udp_socket, freechannel++, ipaddr));
}