1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
/*
ClanLib UDP Tunnel example
This program demonstrates how to use the CL_Socket and CL_IPAddress classes.
It is also excellent to send UDP packets via a third host when playing UT. :)
*/
#include <ClanLib/core.h>
#include <ClanLib/network.h>
#include <iostream>
#ifdef WIN32
#include <windows.h>
#endif
std::map<CL_IPAddress, CL_Socket> forward_sockets;
int main(int argc, char **argv)
{
std::cout << "ClanLib UDP Tunnel, copyright (c) 2001 Magnus Norddahl / Clansoft" << std::endl;
std::cout << std::endl;
if (argc < 4)
{
std::cout << "Syntax: " << argv[0] << " <listen port> <server ip> <server port>" << std::endl;
std::cout << std::endl;
return 255;
}
std::string listen_port = argv[1];
std::string server_ip = argv[2];
std::string server_port = argv[3];
try
{
char data[64*1024];
#ifdef WIN32
CL_SetupCore::set_instance(GetModuleHandle(NULL));
#endif
CL_SetupCore setup_core;
CL_SetupNetwork setup_network;
CL_IPAddress dest(server_ip, server_port);
CL_IPAddress listen_addr;
listen_addr.set_port(listen_port);
CL_Socket listen_sock(CL_Socket::udp);
listen_sock.bind(listen_addr);
#ifdef WIN32 // we need more power on the warp engines for win32
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
#endif
std::cout << "Tunnel is ready." << std::endl;
while (true)
{
fd_set rfds;
FD_ZERO(&rfds);
int highest_fd = listen_sock.get_socket();
FD_SET(listen_sock.get_socket(), &rfds);
std::map<CL_IPAddress, CL_Socket>::iterator it;
for (it = forward_sockets.begin(); it != forward_sockets.end(); it++)
{
int sock = it->second.get_socket();
if (sock > highest_fd) highest_fd = sock;
FD_SET(sock, &rfds);
}
int result = select(highest_fd+1, &rfds, 0, 0, 0);
if (result < 0) throw CL_Error("Select failed!");
if (FD_ISSET(listen_sock.get_socket(), &rfds)) // incoming data from a client
{
try
{
// accept data:
CL_IPAddress from;
int data_size = listen_sock.recv(data, 64*1024, from);
// first find out if we already know the client:
it = forward_sockets.find(from);
if (it == forward_sockets.end()) // new client, create new forward socket for it
{
std::cout << "New client connected!" << std::endl;
CL_Socket new_sock(CL_Socket::udp);
new_sock.bind(CL_IPAddress());
forward_sockets[from] = new_sock;
it = forward_sockets.find(from);
}
// forward the data:
result = it->second.send(data, data_size, dest);
}
catch (CL_Error err)
{
std::cout << "Error while forwarding from client to server " << err.message.c_str() << std::endl;
}
}
for (it = forward_sockets.begin(); it != forward_sockets.end(); it++)
{
const CL_IPAddress &src = it->first;
CL_Socket &forward_sock = it->second;
try
{
int sock = forward_sock.get_socket();
if (FD_ISSET(sock, &rfds)) // incoming data from the server
{
// accept data:
CL_IPAddress from;
int data_size = forward_sock.recv(data, 64*1024, from);
// forward to client:
listen_sock.send(data, data_size, src);
}
}
catch (CL_Error err)
{
std::cout << "Error while forwarding from server to client " << err.message.c_str() << std::endl;
}
}
}
}
catch (CL_Error error)
{
std::cout << "Error: " << error.message.c_str() << std::endl;
}
return 0;
}
|