none
TCP client reciving RRS feed

  • Question

  • Hi all

    I'm working on application that will communicate with hardware wifi module. As communication interface I'm using TCP -module create server and my application connect to server. For my use i am using Visual c++ (2008 express edition) and I tuned up this example code for my purpose:

     http://msdn.microsoft.com/en-us/library/vstudio/system.net.sockets.tcpclient(v=vs.100).aspx  

    Now to the problem, I can connect to server communicate, but server is sometimes sending something 'unexpected', and I'm losing this data. Is it possible to use socket to read data from server asynchronously  or when they are received ? 

    Monday, April 14, 2014 12:28 AM

Answers

All replies

  • See if you get the entire message using the code below.  The sample on the webpage you posted is just to show the syntax of using the method, not code that would actually be used in a real application.  You really need to send a '\n' at the end of each message and then in the receive code wait for the '\n' before processing the data.

    Console.Write("Received: ");         
    While(1)
    {
        Int32 bytes = stream.Read(data, 0, data.Length);
        responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
        Console.Write(responseData);         
    }
    


    jdweng

    Monday, April 14, 2014 1:44 AM
  • I believe that this code is more than working well!  problem is that during the while loop you are not able to do nothing else and i need to be able to call other functions. I'm making windows form application, this is mi code: 
    void Connect( String^ server, String^ message, int port)
    		  {
    			this->TextB_log->Text+="\nConnecting to";
    			this->TextB_log->Text+=server;
    			this->TextB_log->Text+=" on port";
    			this->TextB_log->Text+="port ";
    			this->TextB_log->Text+=port;
    			this->TextB_log->Text+="\n ";
    
    	try
    	{
    		// Create a TcpClient. 
    		
    		client= gcnew TcpClient( server,port );
    		
    	//****************************************************************	
    		//create stream
    		netStream = client->GetStream();
    		
    		con=true;
    	
          // Send the message to the connected TcpServer. 
    		char* buf= (char*)Marshal::StringToHGlobalAnsi(message).ToPointer();
    		int len = strlen(buf);
    		array< Byte >^ data = gcnew array< Byte >(len + 2);
    		Marshal::Copy((IntPtr)buf,data, 0, len);
    
    		this->TextB_log->ForeColor = System::Drawing::Color::Black;
    		netStream->Write( data, 0, data->Length );
    		
    		read();
    	
    		}
    		catch ( ArgumentNullException^ e ) 
    		{
    		  this->TextB_log->Text+=( "ArgumentNullException: {0}", e );
    		}
       
    		/*catch ( SocketException^ e ) 
    		{
    		 this->TextB_log->Text+=( "SocketException: {0}", e );
    		}*/
       }
    
    ////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    
    void send(String^ message )
    		  {
    	//*********************************************************************    
    		// Send the message to the connected TcpServer. 
    	try{	
    		char* buf= (char*)Marshal::StringToHGlobalAnsi(message).ToPointer();
    		int len = strlen(buf);
    		array< Byte >^ data = gcnew array< Byte >(len + 2);
    		Marshal::Copy((IntPtr)buf,data, 0, len);
    		
    
    		netStream->Write( data, 0, data->Length );
    		this->TextB_log->ForeColor = System::Drawing::Color::Red;
    		this->TextB_log->Text+="\n";
    		this->TextB_log->Text+=message;
    	}
    		catch ( ArgumentNullException^ e ) 
    		{
    		  this->TextB_log->Text+=( "ArgumentNullException: {0}", e );
    		}
    
    		read();
       }
    
    /////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    void close ()
    	{
    		client->Close();
    		this->TextB_log->ForeColor = System::Drawing::Color::Green;
    		this->TextB_log->Text+="\nConnection closed";
    		con= false;
    
    	}
    ///////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////
    void read ()
    	{
    		//client->SendTimeout=10;
    	try{
    		client->ReceiveTimeout=500;
    	
    		//netStream->WriteTimeout=10;
    		netStream->ReadTimeout=500;
    
    		array< Byte >^ data;
    		
    		// empty buffer
    		data = gcnew array<Byte>(256);
    		// String to store the response ASCII representation.
    		String^ responseData = String::Empty;
    
          
    //******************************************************************
    		// Read the first batch of the TcpServer response bytes.
            
    	  Int32 bytes = netStream->Read( data, 0, data->Length );
    
    	  String^ dat="";
    	  int i=0;
    	  while(data[i]!=0)
    		{
    			dat+=System::Convert::ToChar(data[i]);
    			i++;
    		}
    		this->TextB_log->ForeColor = System::Drawing::Color::Black;
    		this->TextB_log->Text+=dat;
    
    	 }
    		catch ( ArgumentNullException^ e ) 
    		{
    		  this->TextB_log->Text+=( "ArgumentNullException: {0}", e );
    		}
    
    	  
       }
    ///////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////
    client and net stream are global variables and all functions are called on button event. i would need read without calling the function.
    Monday, April 14, 2014 5:06 AM
  • On the TX side make this change

    From :		char* buf= (char*)Marshal::StringToHGlobalAnsi(message).ToPointer();
    To :		char* buf= (char*)Marshal::StringToHGlobalAnsi(message + "\n").ToPointer();
    

    Then make this change

    	  String^ dat="";
    	  while(1)
    	  {
    	     int i=0;
    	     Int32 bytes = netStream->Read( data, 0, data->Length );
                 while(data[i]!=0)
                 {
    		dat+=System::Convert::ToChar(data[i]);
    		i++;
                  }
                 if(dat->Contains("\n")
                 {
                     break;
                 }            
                  
    	   }
    


    jdweng

    Monday, April 14, 2014 7:03 AM
  • ehem, not sure if that is just me but when I'm constantly calling this line 

     Int32 bytes = netStream->Read( data, 0, data->Length );



    application break down when no data are available 

    Error mesage:

    An unhandled exception of type 'System.IO.IOException' occurred in System.dll

    Additional information: Unable to read data from the transport connection: An established connection was aborted by the software in your host machine.

    Monday, April 14, 2014 6:59 PM
  • You code will spending most of the time inside this method.  It is a synchronous read which blocks until data is returned.  So when the conneciton stops the probability is it will fail while this line is executing.

    jdweng

    Monday, April 14, 2014 7:09 PM
  • Yes, that is true, but this should be protected by ReadTimeout, and i got to another error note :D 

    An unhandled exception of type 'System.IO.IOException' occurred in System.dll

    Additional information: Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.

    how can i catch this? expecting something similar

    catch ( ArgumentNullException^ e ) 
    just protecting tomeout overflow could help me. 


    • Edited by Juro[SK] Monday, April 14, 2014 8:43 PM
    Monday, April 14, 2014 7:59 PM
  • Then general exception should catch everything

    catch ( Exception^ e )

    I believe this exception is caused by the TCP connection not ack the three retries.  Which indicates the an intermediate router/server broke the connection or the other end of the connection is running very slow. 

    You should read another posting from Sunday, April 13, 2014 11:24 AM that a responded to that may help.

    http://social.msdn.microsoft.com/Forums/vstudio/en-US/8bd3cb5c-a41f-4f01-b01b-e6739751bde0/error-of-reading-data-in-socket-programming?forum=csharpgeneral


    jdweng

    Monday, April 14, 2014 9:48 PM