/*---------------------------------------------------------------------- | TcpServerLoop +---------------------------------------------------------------------*/ static void TcpServerLoop(int port) { NPT_TcpServerSocket listener; NPT_Result result = listener.Bind(NPT_SocketAddress(NPT_IpAddress::Any, port)); if (NPT_FAILED(result)) { NPT_Debug("ERROR: Bind() failed (%d)\n", result); } NPT_Socket* client; for (;;) { NPT_Debug("waiting for client on port %d\n", port); NPT_Result result = listener.WaitForNewClient(client); NPT_SocketInfo socket_info; client->GetInfo(socket_info); NPT_Debug("client connected from %s:%d\n", socket_info.remote_address.GetIpAddress().ToString().GetChars(), socket_info.remote_address.GetPort()); NPT_InputStreamReference input; client->GetInputStream(input); NPT_OutputStreamReference output; client->GetOutputStream(output); do { char buffer[1024]; NPT_Size bytes_read; result = input->Read(buffer, sizeof(buffer), &bytes_read); if (NPT_SUCCEEDED(result)) { NPT_Debug("read %ld bytes\n", bytes_read); output->Write(buffer, bytes_read); } } while (NPT_SUCCEEDED(result)); delete client; } }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { // check command line if (argc < 2) { PrintUsageAndExit(); } // init endpoints EndPoint in_endpoint; in_endpoint.direction = ENDPOINT_DIRECTION_IN; EndPoint out_endpoint; out_endpoint.direction = ENDPOINT_DIRECTION_OUT; EndPoint* current_endpoint = &in_endpoint; // init other parameters unsigned int packet_size = PUMP_DEFAULT_PACKET_SIZE; // init options Options.verbose = false; Options.show_progress = false; // parse command line argv++; char* arg; while ((arg = *argv++)) { if (current_endpoint == NULL) { NPT_Debug("ERROR: unexpected argument (%s)\n", arg); exit(1); } if (!strcmp(arg, "--packet-size")) { packet_size = strtoul(*argv++, NULL, 10); continue; } else if (!strcmp(arg, "--verbose")) { Options.verbose = true; continue; } else if (!strcmp(arg, "--show-progress")) { Options.show_progress = true; continue; } else if (!strcmp(arg, "udp")) { if (argv[0] && argv[1]) { if (!strcmp(argv[0], "server")) { if (current_endpoint->direction == ENDPOINT_DIRECTION_OUT){ NPT_Debug("ERROR: cannot use 'udp server' as output\n"); exit(1); } current_endpoint->type = ENDPOINT_TYPE_UDP_SERVER; current_endpoint->info.udp_server.port = strtoul(argv[1], NULL, 10); argv += 2; } else if (!strcmp(argv[0], "client")) { if (current_endpoint->direction == ENDPOINT_DIRECTION_IN) { NPT_Debug("ERROR: cannot use 'udp client' as input\n"); exit(1); } if (argv[2]) { current_endpoint->type = ENDPOINT_TYPE_UDP_CLIENT; current_endpoint->info.udp_client.hostname = argv[1]; current_endpoint->info.udp_client.port = strtoul(argv[2], NULL, 10); argv += 3; } else { NPT_Debug("ERROR: missing argument for 'udp client'\n"); exit(1); } } } else { NPT_Debug("ERROR: missing argument for 'udp' endpoint\n"); exit(1); } } else if (!strcmp(arg, "multicast")) { if (argv[0] && argv[1]) { if (!strcmp(argv[0], "server")) { if (current_endpoint->direction == ENDPOINT_DIRECTION_OUT){ NPT_Debug("ERROR: cannot use 'multicast server' as output\n"); exit(1); } if (argv[2]) { current_endpoint->type = ENDPOINT_TYPE_MULTICAST_SERVER; current_endpoint->info.multicast_server.groupname = argv[1]; current_endpoint->info.multicast_server.port = strtoul(argv[2], NULL, 10); argv += 3; } else { NPT_Debug("ERROR: missing argument for 'multicast server'\n"); exit(1); } } else if (!strcmp(argv[0], "client")) { if (current_endpoint->direction == ENDPOINT_DIRECTION_IN) { NPT_Debug("ERROR: cannot use 'udp client' as input\n"); exit(1); } if (argv[2] && argv[3]) { current_endpoint->type = ENDPOINT_TYPE_MULTICAST_CLIENT; current_endpoint->info.multicast_client.groupname = argv[1]; current_endpoint->info.multicast_client.port = strtoul(argv[2], NULL, 10); current_endpoint->info.multicast_client.ttl = strtoul(argv[3], NULL, 10); argv += 4; } else { NPT_Debug("ERROR: missing argument for 'multicast client'\n"); exit(1); } } } else { NPT_Debug("ERROR: missing argument for 'multicast' endpoint\n"); exit(1); } } else if (!strcmp(arg, "tcp")) { if (argv[0] && argv[1]) { if (!strcmp(argv[0], "server")) { current_endpoint->type = ENDPOINT_TYPE_TCP_SERVER; current_endpoint->info.tcp_server.port = strtoul(argv[1], NULL, 10); argv += 2; } else if (!strcmp(argv[0], "client")) { if (argv[2]) { current_endpoint->type = ENDPOINT_TYPE_TCP_CLIENT; current_endpoint->info.tcp_client.hostname = argv[1]; current_endpoint->info.tcp_client.port = strtoul(argv[2], NULL, 10); argv += 3; } else { NPT_Debug("ERROR: missing argument for 'tcp client'\n"); exit(1); } } } else { NPT_Debug("ERROR: missing argument for 'tcp' endpoint\n"); exit(1); } } else if (!strcmp(arg, "file")) { if (argv[0]) { current_endpoint->type = ENDPOINT_TYPE_FILE; current_endpoint->info.file.name = *argv++; } else { NPT_Debug("ERROR: missing argument for 'file' endpoint\n"); exit(1); } } else if (!strcmp(arg, "serial")) { if (argv[0]) { current_endpoint->type = ENDPOINT_TYPE_SERIAL_PORT; current_endpoint->info.serial_port.name = *argv++; } else { NPT_Debug("ERROR: missing argument for 'serial' endpoint\n"); exit(1); } if (argv[0]) { long speed = 0; if (NPT_FAILED(NPT_ParseInteger(*argv++, speed))) { NPT_Debug("ERROR: invalid speed for 'serial' endpoint\n"); exit(1); } current_endpoint->info.serial_port.speed = (unsigned int)speed; } else { NPT_Debug("ERROR: missing argument for 'serial' endpoint\n"); exit(1); } } else { NPT_Debug("ERROR: invalid argument (%s)\n", arg); exit(1); } if (current_endpoint == &in_endpoint) { current_endpoint = &out_endpoint; } else { current_endpoint = NULL; } } if (current_endpoint) { NPT_Debug("ERROR: missing endpoint specification\n"); exit(1); } // data pump NPT_Result result; // allocate buffer unsigned char* buffer; buffer = (unsigned char*)malloc(packet_size); if (buffer == NULL) { NPT_Debug("ERROR: out of memory\n"); exit(1); } // get output stream NPT_OutputStreamReference out; result = GetEndPointStreams(&out_endpoint, NULL, &out); if (NPT_FAILED(result)) { NPT_Debug("ERROR: failed to get stream for output (%d)", result); exit(1); } unsigned long offset = 0; unsigned long total = 0; if (in_endpoint.type == ENDPOINT_TYPE_UDP_SERVER || in_endpoint.type == ENDPOINT_TYPE_MULTICAST_SERVER) { NPT_UdpSocket* udp_socket; result = GetEndPointUdpSocket(&in_endpoint, udp_socket); // packet loop NPT_DataBuffer packet(32768); NPT_SocketAddress address; do { result = udp_socket->Receive(packet, &address); if (NPT_SUCCEEDED(result)) { if (Options.verbose) { NPT_String ip = address.GetIpAddress().ToString(); NPT_Debug("Received %d bytes from %s\n", packet.GetDataSize(), ip.GetChars()); } result = out->Write(packet.GetData(), packet.GetDataSize(), NULL); offset += packet.GetDataSize(); total += packet.GetDataSize(); } } while (NPT_SUCCEEDED(result)); } else { // get the input stream NPT_InputStreamReference in; result = GetEndPointStreams(&in_endpoint, &in, NULL); if (NPT_FAILED(result)) { NPT_Debug("ERROR: failed to get stream for input (%d)\n", result); exit(1); } // stream loop do { NPT_Size bytes_read; NPT_Size bytes_written; // send result = in->Read(buffer, packet_size, &bytes_read); if (Options.show_progress) { NPT_Debug("[%d]\r", total); } if (NPT_SUCCEEDED(result) && bytes_read) { result = out->Write(buffer, bytes_read, &bytes_written); if (Options.show_progress) { NPT_Debug("[%d]\r", total); } offset += bytes_written; total += bytes_written; } else { printf("[%d] *******************\n", result); exit(1); } } while (NPT_SUCCEEDED(result)); } delete buffer; return 0; }
/*---------------------------------------------------------------------- | ShowResponse +---------------------------------------------------------------------*/ static void ShowResponse(NPT_HttpResponse* response, ShowMode mode) { // show response info NPT_Debug("RESPONSE: protocol=%s, code=%d, reason=%s\n", response->GetProtocol().GetChars(), response->GetStatusCode(), response->GetReasonPhrase().GetChars()); // show headers NPT_HttpHeaders& headers = response->GetHeaders(); NPT_List<NPT_HttpHeader*>::Iterator header = headers.GetHeaders().GetFirstItem(); while (header) { NPT_Debug("%s: %s\n", (const char*)(*header)->GetName(), (const char*)(*header)->GetValue()); ++header; } // show entity NPT_HttpEntity* entity = response->GetEntity(); if (entity != NULL) { NPT_Debug("ENTITY: length=%lld, type=%s, encoding=%s\n", entity->GetContentLength(), entity->GetContentType().GetChars(), entity->GetContentEncoding().GetChars()); switch (mode) { case SHOW_MODE_LOAD: { NPT_DataBuffer body; NPT_Result result =entity->Load(body); if (NPT_FAILED(result)) { NPT_Debug("ERROR: failed to load entity (%d)\n", result); } else { NPT_Debug("BODY: loaded %d bytes\n", (int)body.GetDataSize()); // dump the body NPT_OutputStreamReference output; NPT_File standard_out(NPT_FILE_STANDARD_OUTPUT); standard_out.Open(NPT_FILE_OPEN_MODE_WRITE); standard_out.GetOutputStream(output); output->Write(body.GetData(), body.GetDataSize()); } break; } case SHOW_MODE_STREAM_BLOCKING: { NPT_DataBuffer buffer(4096); NPT_Result result; NPT_InputStreamReference input; entity->GetInputStream(input); do { NPT_Size bytes_read = 0; result = input->Read(buffer.UseData(), 4096, &bytes_read); NPT_Debug("read %d bytes\n", bytes_read); } while (NPT_SUCCEEDED(result)); break; } } } }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int /*argc*/, char** /*argv*/) { // setup debugging #if defined(WIN32) && defined(_DEBUG) int flags = _crtDbgFlag | _CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF; _CrtSetDbgFlag(flags); //AllocConsole(); //freopen("CONOUT$", "w", stdout); #endif NPT_Result result; TcpServerThread* server_thread = NULL; NPT_TcpClientSocket* tcp_client = NULL; NPT_TcpServerSocket* tcp_server = NULL; CancellerThread* canceller = NULL; NPT_SocketAddress address(NPT_IpAddress(127,0,0,1), 10000); #if 0 result = RemoteIpAddress.ResolveName("www.google.com"); CHECK(result == NPT_SUCCESS); NPT_Console::Output("--- test for immediate connection\n"); NPT_Console::Output("[01] starting write server thread\n"); server_thread = new TcpServerThread(); server_thread->Start(); NPT_Console::Output("[01] waiting for server to be ready...\n"); server_thread->m_Ready.WaitUntilEquals(1); NPT_Console::Output("[01] server thread ready\n"); NPT_Console::Output("[01] waiting a while...\n"); NPT_System::Sleep(3.0); tcp_client = new NPT_TcpClientSocket(); NPT_Console::Output("[01] connection to 127.0.0.1:10000\n"); result = tcp_client->Connect(address); NPT_Console::OutputF("[01] connect returns %d : %s\n", result, NPT_ResultText(result)); CHECK(result == NPT_SUCCESS); delete tcp_client; NPT_Console::Output("[01] terminating server\n"); server_thread->m_Interrupted = true; server_thread->Wait(); delete server_thread; NPT_Console::Output("\n--- test for refused local connection\n"); address.SetPort(89); tcp_client = new NPT_TcpClientSocket(); NPT_Console::Output("[01] connecting to 127.0.0.1:89\n"); result = tcp_client->Connect(address); NPT_Console::OutputF("[01] connect returns %d : %s\n", result, NPT_ResultText(result)); CHECK(result == NPT_ERROR_CONNECTION_REFUSED); delete tcp_client; /*NPT_Console::Output("\n--- test for refused remote connection\n"); address.SetIpAddress(RemoteIpAddress); address.SetPort(81); tcp_client = new NPT_TcpClientSocket(); NPT_Console::Output("[01] connecting to www.google.com:81\n"); result = tcp_client->Connect(address); NPT_Console::OutputF("[01] connect returns %d : %s\n", result, NPT_ResultText(result)); CHECK(result == NPT_ERROR_CONNECTION_REFUSED); delete tcp_client;*/ NPT_Console::Output("\n--- test for connection timeout\n"); address.SetIpAddress(NPT_IpAddress(1,1,1,1)); NPT_Console::Output("[01] connecting to 1.1.1.1:89\n"); tcp_client = new NPT_TcpClientSocket(); result = tcp_client->Connect(address, 3000); NPT_Console::OutputF("[01] connect returns %d : %s\n", result, NPT_ResultText(result)); CHECK(result == NPT_ERROR_TIMEOUT); delete tcp_client; NPT_Console::Output("\n--- test for remote connection\n"); address.SetIpAddress(RemoteIpAddress); address.SetPort(80); NPT_Console::Output("[01] connecting to www.google.com:80\n"); tcp_client = new NPT_TcpClientSocket(); result = tcp_client->Connect(address); NPT_Console::OutputF("[01] connect returns %d : %s\n", result, NPT_ResultText(result)); CHECK(result == NPT_SUCCESS); delete tcp_client; #endif for (int i=0; i<2; i++) { NPT_Console::OutputF("\n--- test for cancelled connection, shutdown=%d\n", i); address.SetIpAddress(NPT_IpAddress(1,1,1,1)); address.SetPort(89); NPT_Console::Output("[01] connecting to 1.1.1.1:89\n"); tcp_client = new NPT_TcpClientSocket(NPT_SOCKET_FLAG_CANCELLABLE); canceller = new CancellerThread(tcp_client, 3.0f, i==1); result = tcp_client->Connect(address); NPT_Console::OutputF("[01] connect returns %d : %s\n", result, NPT_ResultText(result)); CHECK(result == NPT_ERROR_CANCELLED); canceller->Wait(); delete canceller; delete tcp_client; } for (int i=0; i<2; i++) { NPT_Console::OutputF("\n--- testing read cancellation, shutdown=%d\n", i); address.SetIpAddress(RemoteIpAddress); address.SetPort(80); NPT_Console::Output("[01] connecting to www.google.com:80\n"); tcp_client = new NPT_TcpClientSocket(NPT_SOCKET_FLAG_CANCELLABLE); result = tcp_client->Connect(address); NPT_Console::OutputF("[01] connect returns %d : %s\n", result, NPT_ResultText(result)); CHECK(result == NPT_SUCCESS); canceller = new CancellerThread(tcp_client, 3.0f, i==1); NPT_InputStreamReference input; tcp_client->GetInputStream(input); unsigned char buffer[4096]; NPT_SetMemory(buffer, 0, sizeof(buffer)); result = input->Read(buffer, 4096); NPT_Console::OutputF("{00} read returned %d (%s)\n", result, NPT_ResultText(result)); CHECK(result == NPT_ERROR_CANCELLED); delete tcp_client; canceller->Wait(); delete canceller; } for (int i=0; i<2; i++) { NPT_Console::OutputF("\n--- testing write cancellation, shutdown=%d\n", i); server_thread = new TcpServerThread(); server_thread->Start(); NPT_Console::Output("[01] waiting for server to be ready...\n"); server_thread->m_Ready.WaitUntilEquals(1); NPT_Console::Output("[01] server thread ready\n"); NPT_Console::Output("[01] waiting a while...\n"); NPT_System::Sleep(3.0); address.SetIpAddress(NPT_IpAddress(127,0,0,1)); address.SetPort(10000); NPT_Console::Output("[01] connecting to localhost:10000\n"); tcp_client = new NPT_TcpClientSocket(NPT_SOCKET_FLAG_CANCELLABLE); result = tcp_client->Connect(address); NPT_Console::OutputF("[01] connect returns %d : %s\n", result, NPT_ResultText(result)); CHECK(result == NPT_SUCCESS); canceller = new CancellerThread(tcp_client, 3.0f, i==1); NPT_OutputStreamReference output; tcp_client->GetOutputStream(output); NPT_Size total_written = 0; unsigned char buffer[4096]; NPT_SetMemory(buffer, 0, sizeof(buffer)); do { NPT_Size bytes_written = 0; result = output->Write(buffer, 4096, &bytes_written); if (NPT_SUCCEEDED(result)) { total_written += bytes_written; } } while (NPT_SUCCEEDED(result)); output = NULL; NPT_Console::OutputF("{01} write returned %d (%s)\n", result, NPT_ResultText(result)); NPT_Console::OutputF("{01} wrote %d bytes total\n", total_written); CHECK(result == NPT_ERROR_CANCELLED); delete tcp_client; canceller->Wait(); delete canceller; server_thread->m_Interrupted = true; server_thread->Wait(); delete server_thread; } for (int i=0; i<2; i++) { NPT_Console::OutputF("\n--- testing accept cancellation, shutdown=%d\n", i); NPT_Console::Output("{03} waiting for connection on port 10000\n"); address.SetIpAddress(NPT_IpAddress(127,0,0,1)); address.SetPort(10000); tcp_server = new NPT_TcpServerSocket(NPT_SOCKET_FLAG_CANCELLABLE); result = tcp_server->Bind(address, true); CHECK(result == NPT_SUCCESS); canceller = new CancellerThread(tcp_server, 3.0f, i==1); NPT_Socket* new_client = NULL; result = tcp_server->WaitForNewClient(new_client); NPT_Console::OutputF("{03} WaitForNewClient returned %d (%s)\n", result, NPT_ResultText(result)); CHECK(result == NPT_ERROR_CANCELLED); canceller->Wait(); delete canceller; delete tcp_server; } NPT_Console::Output("------------\n"); NPT_Console::Output("bye bye\n"); #if defined(WIN32) && defined(_DEBUG) _CrtDumpMemoryLeaks(); #endif return 0; }