Trap socket error 10055

This is the forum for miscellaneous technical/programming questions.

Moderator: 2ffat

mark_c
BCBJ Master
BCBJ Master
Posts: 244
Joined: Thu Jun 21, 2012 1:13 am

Trap socket error 10055

Post by mark_c »

hello,
i writed a simple Client wich try four port range (80, 8081, 5000, 8345) and ip range from 100.45.67.89 to 200.234.34.234
The sequence operations are following:
1) set ip address
2) set port number
3) try connection
if connection ok
4) close connection and set next port number
a the end of port range, set next ip range and so on
if no success
5) try next port range number
a the end of port range, try next ip range adress

Well, some time I get socket error 10055 by i don't know how to trap this.

I found a short example that captures the 10055 exception with Listen, but for me it is incorrect to use it in BCB6, is there another way to capture the 10055 error?

Code: Select all

try
{
  IPEndPoint localEndPoint;
  localEndPoint = new IPEndPoint(IPAddress.Any,listenPort);

  sock = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
  sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger,1);
  sock.SetSocketOption(SocketOptionLevel.Tcp,SocketOptionName.NoDelay,1);

  sock.Bind(localEndPoint);
  sock.Listen(128); // <--- SocketException
  sock.BeginAccept(new AsyncCallback(Callback),sock);
}
catch (SocketException socketException)
{

} 
note: socket is set nonblocking
rlebeau
BCBJ Author
BCBJ Author
Posts: 1701
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA
Contact:

Re: Trap socket error 10055

Post by rlebeau »

Please show YOUR actual code that you are having trouble with. It likely has a bug in it. But we can't see what that is. Posting someone else's workaround code is useless without context.
Remy Lebeau (TeamB)
Lebeau Software
mark_c
BCBJ Master
BCBJ Master
Posts: 244
Joined: Thu Jun 21, 2012 1:13 am

Re: Trap socket error 10055

Post by mark_c »

no problem, original code it's similar 100% to this code.
Error 10055 occurs after many hours, and no for obvious reason.

thank you

Code: Select all

//---------------------------------------------------------------------------
#include
#pragma hdrstop
#include "Unit1.h"
bool isopen;
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
	AnsiString myip;
	Memo1->Clear();

	for( int g=1; g<255;g++ )
	{
		for( int i=1; i<255;i++ ) 
		{ 
			if(ClientSocket1->Active)
				ClientSocket1->Close();
			
			myip.sprintf("1.1.%d.%d",g, i);

// In this example the pot is deliberately kept fixed
// I don't think that's the problem is here
// error 10055 occurs after many hours, and no for obvious reason

			ClientSocket1->Host=myip;
			ClientSocket1->Port=80;
			ClientSocket1->Open();

			while(isopen)
			{
				Sleep(20);
				Application->ProcessMessages();
				Caption=myip;
			}
		}
	}
	Button1->Enabled=true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ClientSocket1Error(TObject *Sender,
TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
	Memo1->Lines->Add(ErrorCode);
	ErrorCode = 0;
	isopen=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Lookup(TObject *Sender,
TCustomWinSocket *Socket)
{
	isopen=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Disconnect(TObject *Sender,
TCustomWinSocket *Socket)
{
	isopen=false;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ClientSocket1Connect(TObject *Sender,
TCustomWinSocket *Socket)
{
	isopen=false;
}
//---------------------------------------------------------------------------
rlebeau
BCBJ Author
BCBJ Author
Posts: 1701
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA
Contact:

Re: Trap socket error 10055

Post by rlebeau »

mark_c wrote:no problem, original code it's similar 100% to this code.
Error 10055 occurs after many hours, and no for obvious reason.
Have a look at these past discussions:

http://www.delphigroups.info/2/cc/193138.html

https://stackoverflow.com/questions/47158231/

In a nutshell, you need to call Socket->Close() in the OnError event:

Code: Select all

void __fastcall TForm1::ClientSocket1Error(TObject *Sender, TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
   Memo1->Lines->Add(ErrorCode);
   ErrorCode = 0;
   Socket->Close(); // <-- HERE
   isopen=false;
}
That being said, you really should NOT be using a ProcessMessages() loop at all. If you are using the socket in non-blocking mode (the default), you should re-write the code to be truly event driven and get rid of the blocking loop altogether, eg:

Code: Select all

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
int g, i;
AnsiString myip;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   Button1->Enabled = false;
   g = 0;
   i = 255;
   myip = "";
   Memo1->Clear();
   NextIP();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::NextIP()
{
   if (i == 255)
   {
      if (g == 255)
      {
         Button1->Enabled = true;
         return;
      }
      ++g;
      i = 1;
   }
   else
      ++i;

   myip.sprintf("1.1.%d.%d", g, i);
   Caption = myip;

   ClientSocket1->Host = myip;
   ClientSocket1->Port = 80;
   ClientSocket1->Open();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Error(TObject *Sender, TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
   Memo1->Lines->Add(ErrorCode);
   ErrorCode = 0;
   Socket->Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Connect(TObject *Sender, TCustomWinSocket *Socket)
{
   Socket->Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Disconnect(TObject *Sender, TCustomWinSocket *Socket)
{
   NextIP();
}
//---------------------------------------------------------------------------
Otherwise, set the socket to blocking mode and get rid of ProcessMessages() completely, and the event handlers, you won't need them anymore:

Code: Select all

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   Button1->Enabled = false;

   AnsiString myip;
   Memo1->Clear();

   for (int g = 1; g < 255; ++g)
   {
      for (int i = 1; i < 255; ++i)
      {
         myip.sprintf("1.1.%d.%d",g, i);
         Caption = myip;
         Update();

         ClientSocket1->Host = myip;
         ClientSocket1->Port = 80;

         try
         {
            ClientSocket1->Open();
         }
         catch (const Exception &e)
         {
            Memo1->Lines->Add(e.Message);
         }

         ClientSocket1->Close();
      }
   }

   Button1->Enabled = true;
}
//---------------------------------------------------------------------------
In this case, it would be better to move the TClientSocket operations to a worker thread that posts status updates to the UI thread when needed.
Remy Lebeau (TeamB)
Lebeau Software
mark_c
BCBJ Master
BCBJ Master
Posts: 244
Joined: Thu Jun 21, 2012 1:13 am

Re: Trap socket error 10055

Post by mark_c »

thanks remy,
however as you saw, before opening a socket I always check that it is not already open and if so I close it:

Code: Select all

          if (ClientSocket1->Active)
             ClientSocket1->Close();
is this control not enough in case of socket error?
mark_c
BCBJ Master
BCBJ Master
Posts: 244
Joined: Thu Jun 21, 2012 1:13 am

Re: Trap socket error 10055

Post by mark_c »

I have a problem: supposing I want to instantiate 100 threads with the above code and thus have 100 simultaneous TCP connections, how do I handle the OnConnect event for 100 threads?
I think there would be a race condition problem, am I wrong?
Do I need to find a way to sync this event?
rlebeau
BCBJ Author
BCBJ Author
Posts: 1701
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA
Contact:

Re: Trap socket error 10055

Post by rlebeau »

You would have to create 100 TClientSocket objects, each with an OnConnect handler assigned. Best to have each thread create its own TClientSocket object. You can use a single method for all 100 events, such as a method of the thread class. You can use the event's Sender parameter to know which TClientSocket object is firing the event. You don't need to sync the events unless they access resources that are shared across threads, or if they need to make UI updates.
Remy Lebeau (TeamB)
Lebeau Software
mark_c
BCBJ Master
BCBJ Master
Posts: 244
Joined: Thu Jun 21, 2012 1:13 am

Re: Trap socket error 10055

Post by mark_c »

so use a single socket for 100 threads, the socket created statically by the main thread at runtime to understand and share it would be wrong, right?
This is because the various threads in execution would remain in the queue waiting for their turn to access the only shared socket; in this case then, I should synchronize every access to the socket, right?
rlebeau
BCBJ Author
BCBJ Author
Posts: 1701
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA
Contact:

Re: Trap socket error 10055

Post by rlebeau »

mark_c wrote:so use a single socket for 100 threads, the socket created statically by the main thread at runtime to understand and share it would be wrong, right?
For 100 TCP connections, you would need 100 sockets. Each thread would have its own socket that it manages separate from every other thread.
mark_c wrote:This is because the various threads in execution would remain in the queue waiting for their turn to access the only shared socket; in this case then, I should synchronize every access to the socket, right?
No, not even close.
Remy Lebeau (TeamB)
Lebeau Software
mark_c
BCBJ Master
BCBJ Master
Posts: 244
Joined: Thu Jun 21, 2012 1:13 am

Re: Trap socket error 10055

Post by mark_c »

sorry, ultimately, what I want to achieve is to have 100 threads running, each with its private socket and its events: is it possible?
HsiaLin
BCBJ Master
BCBJ Master
Posts: 329
Joined: Sun Jul 08, 2007 6:29 pm

Re: Trap socket error 10055

Post by HsiaLin »

Just curious, you aren't trying to make a Low Earth Orbit Ion Cannon are you?
mark_c
BCBJ Master
BCBJ Master
Posts: 244
Joined: Thu Jun 21, 2012 1:13 am

Re: Trap socket error 10055

Post by mark_c »

HsiaLin wrote:Just curious, you aren't trying to make a Low Earth Orbit Ion Cannon are you?
:lol: :lol: :lol:
don't worry, they are only didactic experiments.

I'll give you an example: if you want to scan 2^32 internet addresses and for each one it takes 1 second, it would take 136 years to scan them all; we would already be beautiful than dead. So, the idea is to use either 136 computers and take 1 year or, 1 program with a certain number of threads and sockets.

I hope I have satisfied your curiosity?

When we have quantum computers at our disposal, these types of problems will no longer exist, let's be patient.
rlebeau
BCBJ Author
BCBJ Author
Posts: 1701
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA
Contact:

Re: Trap socket error 10055

Post by rlebeau »

mark_c wrote:sorry, ultimately, what I want to achieve is to have 100 threads running, each with its private socket and its events: is it possible?
Yes, it is, exactly as I described earlier. Is there a particular issue you are having with understanding what I described? What have you actually tried that is not working for you?

And BTW, if you use TClientSocket inside a thread, it is best NOT to use events at all. Use the TClientSocket in thread-blocking mode instead. It will make writing the thread code much simpler. If you use TClientSocket in non-blocking mode in a thread, then you have to give each thread its own message loop, which is overkill if the threads don't have other elements that also need a message loop (UIs, STA COM objects, etc).
Remy Lebeau (TeamB)
Lebeau Software
mark_c
BCBJ Master
BCBJ Master
Posts: 244
Joined: Thu Jun 21, 2012 1:13 am

Re: Trap socket error 10055

Post by mark_c »

sorry Remy if sometimes I repeat the same things, maybe the same as you said, but unfortunately I don't know much about multi-thread programming in addition to sockets, even almost for nothing.
However I started writing some code that now works, using precisely, as you suggested, blocking sockets because, as you say, they are easier to manage. I saw on the net your answer where you explained to a user the use of non-blocking sckets, where you answered that you have to create a loop that continuously reads the system messages and you have to act accordingly, for now it is too complex.
So, I use blocking sockets which are easier to manage.
rlebeau
BCBJ Author
BCBJ Author
Posts: 1701
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA
Contact:

Re: Trap socket error 10055

Post by rlebeau »

mark_c wrote:sorry Remy if sometimes I repeat the same things, maybe the same as you said, but unfortunately I don't know much about multi-thread programming in addition to sockets, even almost for nothing.
This has less to do with threading, and more to do with general OOP design. You have a Thread class. Give it a TClientSocket data member, and create/destroy the TClientSocket inside the Thread class as needed. Then create 100 instances of your Thread class.
Remy Lebeau (TeamB)
Lebeau Software
Post Reply