sendrecv_test.cpp
来自「ACE编程的一本经典BIBLE的源代码,喜欢网络编程的别错过」· C++ 代码 · 共 389 行
CPP
389 行
// SendRecv_Test.cpp,v 1.3 2005/01/21 02:19:20 ossama Exp
// ===========================================================================
//
// = LIBRARY
// tests
//
// = FILENAME
// Send_Recv_Test.cpp
//
// = DESCRIPTION This is a test of the <ACE_SOCK>'s various send and
// receive methods, over HTBP. The test forks two processes or spawns
// two threads (depending upon the platform) and then executes client
// and server allowing them to connect and exchange data in ways
// designed to exercise the send and recv functions.
//
// Right now, it primarily tests the iov-like send and recv
// functions, but others should be added to completely cover the
// possible scenarios.
//
// = AUTHOR
// Steve Huston <shuston@riverace.com>
//
// ============================================================================
#include "tests/test_config.h"
#include "ace/HTBP/HTBP_Stream.h"
#include "ace/HTBP/HTBP_Session.h"
#include "ace/HTBP/HTBP_ID_Requestor.h"
#include "ace/HTBP/HTBP_Environment.h"
#include "ace/OS.h"
#include "ace/Thread.h"
#include "ace/Thread_Manager.h"
#include "ace/SOCK_Connector.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/SOCK_Stream.h"
ACE_RCSID(tests,
SOCK_Send_Recv_Test,
"SendRecv_Test.cpp,v 1.3 2005/01/21 02:19:20 ossama Exp")
// Change to non-zero if test fails
static int Test_Result = 0;
#if !defined (ACE_LACKS_FORK) || defined (ACE_HAS_THREADS)
// In test 3, a large amount of data is sent. The purpose is to overflow the
// TCP send window, causing the sender to block (it's a send_n). This value
// is the amount to send. The assumption is that no implementation has a
// receive window larger than 128K bytes. If one is found, this is the place
// to change it.
// For some odd reason, NT will try to send a single large buffer, but not
// multiple smaller ones that add up to the large size.
const size_t Test3_Send_Size = 4*1024;
const size_t Test3_Loops = 10;
const size_t Test3_Total_Size = Test3_Send_Size * Test3_Loops;
static void *
client (void *arg)
{
ACE_OS::socket_init (ACE_WSOCK_VERSION);
ACE::HTBP::Environment ht_env;
#if 0 // this needs to take the config file name as an argument.
ht_env.import_config ("../HTBP_Config.conf");
#endif /* 0 */
ACE::HTBP::ID_Requestor req (&ht_env);
ACE::HTBP::Addr local(ACE_TEXT_ALWAYS_CHAR(req.get_HTID()));
char hostname [128];
if (ACE_OS::hostname (hostname,128) == -1)
ACE_ERROR_RETURN ((LM_ERROR, "Could not get the host name\n"),0);
ACE_INET_Addr *remote_addr = reinterpret_cast<ACE_INET_Addr *> (arg);
ACE::HTBP::Addr remote (remote_addr->get_port_number (),hostname);
unsigned pport;
ACE_TString phost;
ht_env.get_proxy_port(pport);
ht_env.get_proxy_host(phost);
ACE_INET_Addr proxy(pport,phost.c_str());
ACE::HTBP::Session session(remote,local,ACE::HTBP::Session::next_session_id(),&proxy);
ACE::HTBP::Stream stream(&session);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%P|%t) Connecting to port %d\n"),
remote.get_port_number()));
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%P|%t) connected to %s\n"),
ACE_TEXT_CHAR_TO_TCHAR(remote.get_host_name ())));
//******************* TEST 1 ******************************
//
// Do a iovec sendv - send the 255 byte buffer in 5 chunks. The
// server will verify that the correct data is sent, and that there
// is no more and no less.
u_char buffer[255];
size_t i;
ssize_t len;
// The server will verify that this data pattern gets there intact.
for (i = 0; i < sizeof buffer; ++i)
buffer[i] = static_cast<u_char> (i);
iovec iov[5];
iov[0].iov_base = reinterpret_cast<char *> (&buffer[0]);
iov[0].iov_len = 50;
iov[1].iov_base = reinterpret_cast<char *> (&buffer[50]);
iov[1].iov_len = 25;
iov[2].iov_base = reinterpret_cast<char *> (&buffer[75]);
iov[2].iov_len = 150;
iov[3].iov_base = reinterpret_cast<char *> (&buffer[225]);
iov[3].iov_len = 29;
iov[4].iov_base = reinterpret_cast<char *> (&buffer[254]);
iov[4].iov_len = 1;
len = stream.sendv (iov, 5);
if (len == -1)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("(%P|%t) %p\n"),
ACE_TEXT ("Test 1, sendv failed")));
Test_Result = 1;
}
else
ACE_ASSERT (len == 255);
ACE_DEBUG ((LM_DEBUG, "***** client TEST 2 ***** \n"));
//******************* TEST 2 ******************************
//
// The same data is coming back - receive it using recv (size_t n,
// ...) and compare it to the original data.
u_char buffer2[255];
// Give it a chance to get here
ACE_OS::sleep (2);
len = stream.recv_n (buffer2,
155);
len = stream.recv_n (buffer2,
105);
for (i = 0; i < 255; i++)
if (buffer2[i] != buffer[i])
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("(%P|%t) Test 2, rcvd byte %d is %d, not %d\n"),
i, buffer2[i], buffer[i]));
Test_Result = 1;
}
stream.close ();
return 0;
}
static void *
server (void *arg)
{
ACE_OS::socket_init (ACE_WSOCK_VERSION);
ACE_SOCK_Acceptor *peer_acceptor = (ACE_SOCK_Acceptor *) arg;
ACE_INET_Addr cli_addr;
ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT);
ACE_SOCK_Stream sock[2];
ACE_DEBUG ((LM_DEBUG,"server is ready\n"));
if (peer_acceptor->accept(sock[0],&cli_addr,&timeout) == -1)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("(%P|%t) %p\n"),
ACE_TEXT ("accept")));
Test_Result = 1;
return 0;
}
ACE::HTBP::Channel channel1(sock[0]);
ACE_DEBUG ((LM_DEBUG,"Got sock[0], handle = %d\n",sock[0].get_handle()));
if (peer_acceptor->accept(sock[0],&cli_addr,&timeout) == -1)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("(%P|%t) %p\n"),
ACE_TEXT ("accept")));
Test_Result = 1;
return 0;
}
ACE::HTBP::Channel channel2(sock[1]);
ACE_DEBUG ((LM_DEBUG,"Got sock[1], handle = %d\n",sock[1].get_handle()));
int res = 0;
while ((res = channel1.pre_recv()) != 0)
{
ACE_DEBUG ((LM_DEBUG,"res = %d. waiting 1 sec. %p\n",res,
"stream.pre_recv()"));
ACE_OS::sleep (1);
}
ACE_DEBUG ((LM_DEBUG,"Read from channel2\n"));
while ((res = channel2.pre_recv()) != 0)
{
ACE_DEBUG ((LM_DEBUG,"res = %d, waiting 1 sec. %p\n",res,
"stream2.pre_recv()"));
ACE_OS::sleep (1);
}
ACE::HTBP::Session *session = channel1.session();
ACE::HTBP::Stream stream (session);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%P|%t) client %s connected from %d\n"),
ACE_TEXT_CHAR_TO_TCHAR(cli_addr.get_host_name ()),
cli_addr.get_port_number ()));
//******************* TEST 1 ******************************
//
// Do a iovec recvv - the client should send 255 bytes, which we
// will be detected and read into a ACE-allocated buffer. Use a 5
// second timeout to give the client a chance to send it all.
ACE_OS::sleep (5);
u_char buffer[255];
iovec iov[3];
ssize_t len;
int i;
iov[0].iov_base = reinterpret_cast<char *> (&buffer[0]);
iov[0].iov_len = 75;
iov[1].iov_base = reinterpret_cast<char *> (&buffer[75]);
iov[1].iov_len = 100;
iov[2].iov_base = reinterpret_cast<char *> (&buffer[175]);
iov[2].iov_len = 80;
len = stream.recvv (iov, 3);
if (len == -1)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("(%P|%t) %p\n"),
ACE_TEXT ("Test 1, recvv failed")));
Test_Result = 1;
}
for (i = 0; i < 255; i++)
if (buffer[i] != i)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("(%P|%t) Test 1, rcvd byte %d is %d, not %d\n"),
i,
buffer[i],
i));
Test_Result = 1;
}
ACE_DEBUG ((LM_DEBUG, "***** TEST 2 ***** \n"));
//******************* TEST 2 ******************************
//
// Send the buffer back, using send (size_t n, ...) in 3 pieces.
len = stream.send (buffer, 6);
len += stream.send (buffer,42);
len += stream.send (buffer,189);
len += stream.send_n (buffer,18);
ACE_ASSERT (len == 255);
sock[0].close();
sock[1].close();
stream.close ();
return 0;
}
#endif /* !ACE_LACKS_FORK || ACE_HAS_THREADS */
static void
spawn (void)
{
// Acceptor
ACE_SOCK_Acceptor peer_acceptor;
// Create a server address.
ACE_INET_Addr server_addr;
char hostname[BUFSIZ];
if (ACE_OS::hostname (hostname, BUFSIZ) != 0)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("Could not get the hostname\n")));
}
ACE::HTBP::Addr addr (8088, hostname);
// Bind listener to any port and then find out what the port was.
if (peer_acceptor.open (addr) == -1
|| peer_acceptor.get_local_addr (server_addr) == -1)
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("(%P|%t) %p\n"),
ACE_TEXT ("open")));
else
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%P|%t) starting server at port %d\n"),
server_addr.get_port_number ()));
#if !defined (ACE_LACKS_FORK)
switch (ACE_OS::fork (ACE_TEXT("child")))
{
case -1:
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("(%P|%t) %p\n%a"),
ACE_TEXT ("fork failed"),
1));
/* NOTREACHED */
case 0:
client (&server_addr);
ACE_OS::exit (0);
/* NOTREACHED */
default:
server (reinterpret_cast<void *> (&peer_acceptor));
ACE_OS::wait ();
}
#elif defined (ACE_HAS_THREADS)
if (ACE_Thread_Manager::instance ()->spawn
(ACE_THR_FUNC (server),
reinterpret_cast<void *> (&peer_acceptor),
THR_NEW_LWP | THR_DETACHED) == -1)
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("(%P|%t) %p\n%a"),
ACE_TEXT ("thread create failed"),
1));
if (ACE_Thread_Manager::instance ()->spawn
(ACE_THR_FUNC (client),
reinterpret_cast<void *> (&server_addr),
THR_NEW_LWP | THR_DETACHED) == -1)
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("(%P|%t) %p\n%a"),
ACE_TEXT ("thread create failed"),
1));
// Wait for the threads to exit.
ACE_Thread_Manager::instance ()->wait ();
#else
ACE_ERROR ((LM_INFO,
ACE_TEXT ("(%P|%t) ")
ACE_TEXT ("only one thread may be run ")
ACE_TEXT ("in a process on this platform\n")));
#endif /* ACE_HAS_THREADS */
peer_acceptor.close ();
}
}
int
ACE_TMAIN (int, ACE_TCHAR *[])
{
ACE_START_TEST (ACE_TEXT ("SOCK_Send_Recv_Test"));
spawn ();
ACE_END_TEST;
return Test_Result;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?