In my setup, I use a PC (laptop) with Win7 that creates a hosted network (WiFi). I program it in C++/CLI (.net). On the other side, I have a tablet with Android (ICS). The tablet is the server and the PC is the client. I chose TCP for accuracy, I exchange commands, I don't want to loose packets.
On the tablet side, I use a ServerSocket
that waits for communication with the method accept()
. Then it returns a Socket
, etc.
On the PC side, I use a Socket
then I connect it to the tablet using connect()
. After it is done, I send()
bytes to the tablet that get them through its InputBuffer
... The it returns bytes through its OutputBuffer
and they are retrieved in the PC by calling receive()
.
The problem is that sometimes it takes few seconds for a send/receive cycle, other times it takes few tens of milliseconds. So here are my questions:
- Is it a normal behavior that we can expect for such communications?
- Can we fine tune this behavior by setting, say, buffer sizes or other things?
- What is the longest step: connecting or transferring data?
I would appreciate if someone could give me some clues. I'm pretty new in network programmation and sometime "I'm loosing my latin!" (well... a french expression!)
Code examples: (skipping trivial code and comments...)
PC side (C++/CLI)
Socket^ lpSocket = gcnew Socket( SocketType::Stream, ProtocolType::Tcp );
lpSocket->Connect( Addr, Port ); // PROBLEMS HERE
SocketError err;
array<Byte>^ lOutBuffer = Encoding::UTF8->GetBytes( "Here's a sentence.\r\n" );
lpSocket->Send( lOutBuffer, 0, lOutBuffer->Length, SocketFlags::None, err );
array<Byte>^ lInBuffer = gcnew array<Byte>( 1024 );
int N = lpSocket->Receive( lInBuffer, 0, lInBuffer->Length, SocketFlags::None, err );
String^ lpOutString = Encoding::UTF8->getString( lInBuffer, 0, N );
Tablet side (Android ICS) The code is a little more complicated due to threading. I will skip the mandatory try/catch...
// ... We are in a background thread
ServerSocket mSS = new ServerSocket();
mSS.bind( new InetSocketAddress( mPort ) );
mSS.setReuseAddress( true );
Socket lCS = mSS.accept();
lCS.setSoTimeout( 1 );
lCS.setTcpNoDelay( true );
BufferedInputStream lIn = new BufferedInputStream( lCS.getInputStream() );
PrintStream lPS = new PrintStream( lCS.getOutputStream() );
byte[] lBuf = new byte[1024];
String lInStr="";
while ( true )
{
try
{
if ( lInStr.endsWith( "\r\n" ) ) { break; }
int N;
if ((N=lIn.read( lBuf,0,1024))!=-1) { lInStr += new String( lBuf, 0, N, "UTF-8" );}
else { break; }
}
catch ( SocketTimeoutException e )
{ /* Can occur because timeout is set to 1ms */ }
}
lOut.print( lInStr ); // Just echo input to output
lOut.close();
lCS.close();
mSS.close();
So, it is a simple app where I can accept one connection. Once it is accepted, I process it, then I close the sockets and that's it.
The problems occur (it seems) in the PC side with connect()
. I often get error Timeout or ConnectionRefused. If I redo the connect()
in a loop, I obtain a connection. But even when there is no timeout, the connection can take few seconds to establish.