Board index » delphi » 10048 WSAEADDRINUSE "Address already in use" Error

10048 WSAEADDRINUSE "Address already in use" Error


2004-09-29 10:03:55 PM
delphi173
Hello,
I am using the TTcpClient object in a multi-threaded application to
simultaneously communicate to several field devices. I am using one
TTcpClient object in each of my communications threads. The application
seems to work pretty well for the most part but I get the following Winsock
Error on a regular basis: Any suggestions on resolving the problem would be
much appreciated. Details on the issue are show below:
###################################
WSAEADDRINUSE
(10048)
Address already in use.
Only one usage of each socket address (protocol/IP address/port) is normally
permitted. This error occurs if an application attempts to bind a socket to
an IP address/port that has already been used for an existing socket, or a
socket that wasn't closed properly, or one that is still in the process of
closing. For server applications that need to bind multiple sockets to the
same port number, consider using setsockopt
(SO_REUSEADDR). Client applications usually need not call bind at all -
connect will choose an unused port automatically.
#####################################
I use the following sequence to open, communicate and then close the
connections:: This code only gives the general sequence, the actual code
is complex with error handling etc. Extra code has been removed for this
example.
TCPClient.Open;
repeat
BytesRead := TCPClient.ReceiveBuf(RxBuf,RxBufSize);
// dosomething with received data
// send out data if necessary
if [Needed] then
TCPClient.Sendln(MsgSendStr,'');
until [Finished Processing]
TCPClient.Close;
After communications is complete with one unit, there is a delay of one
secnod and then the process is repeated with another unit.
In my testing, I have 5 units in the test which are communicated with
repeatadly in this fashion. The error seems to occur every 1-15 minutes or
so.
How can I work around this problem?
Thanks,
Greg Dunn
XXXX@XXXXX.COM
304-757-6565 ext 117
 
 

Re:10048 WSAEADDRINUSE "Address already in use" Error

You have one item listening on a port for data to come in, another item
then tries to listen on the same port, causing the error.
Have one client open for all the machines to talk to, dont keep opening
and closing, then have some way to distinguish which machine is which.
Gavin
Quote
Hello,

I am using the TTcpClient object in a multi-threaded application to
simultaneously communicate to several field devices. I am using one
TTcpClient object in each of my communications threads. The application
seems to work pretty well for the most part but I get the following Winsock
Error on a regular basis: Any suggestions on resolving the problem would be
much appreciated. Details on the issue are show below:

###################################
WSAEADDRINUSE

(10048)

Address already in use.

Only one usage of each socket address (protocol/IP address/port) is normally
permitted. This error occurs if an application attempts to bind a socket to
an IP address/port that has already been used for an existing socket, or a
socket that wasn't closed properly, or one that is still in the process of
closing. For server applications that need to bind multiple sockets to the
same port number, consider using setsockopt
(SO_REUSEADDR). Client applications usually need not call bind at all -
connect will choose an unused port automatically.
#####################################

I use the following sequence to open, communicate and then close the
connections:: This code only gives the general sequence, the actual code
is complex with error handling etc. Extra code has been removed for this
example.

TCPClient.Open;

repeat
BytesRead := TCPClient.ReceiveBuf(RxBuf,RxBufSize);
// dosomething with received data

// send out data if necessary
if [Needed] then
TCPClient.Sendln(MsgSendStr,'');

until [Finished Processing]

TCPClient.Close;


After communications is complete with one unit, there is a delay of one
secnod and then the process is repeated with another unit.

In my testing, I have 5 units in the test which are communicated with
repeatadly in this fashion. The error seems to occur every 1-15 minutes or
so.

How can I work around this problem?

Thanks,
Greg Dunn
XXXX@XXXXX.COM
304-757-6565 ext 117
 

Re:10048 WSAEADDRINUSE "Address already in use" Error

"Gavin Watkinson" <XXXX@XXXXX.COM>writes
Quote
You have one item listening on a port for data to come in, another item
then tries to listen on the same port, causing the error.

Have one client open for all the machines to talk to, dont keep opening
and closing, then have some way to distinguish which machine is which.

Gavin

Gregory's app is a little odd, with all that connecting, reconnecting &
polling. I too, would think that leaving the connections open would be
better, especially with only 5 servers.
Nevertheless, how could 'Address already in use' occur at a TCP client? I
can understand that the number of client sockets could easily run out on the
{*word*99}pier OS, eg W98, if there was a lot of open/close that used up sockets
faster than they could be recycled by winsock, (since it takes 2 mins
default for the wait timer to expire). But would this not give a different
error message? I am sure I have done this with a server test app that
created/opened/closed lots of clients & the error was not 10048.
Rgds,
Martin
 

Re:10048 WSAEADDRINUSE "Address already in use" Error

Saw the error msg and got it into my head it was a server - doh.
With the indy TcpClient are you setting the boundip and boundport
properties?
Gavin
Quote
Gregory's app is a little odd, with all that connecting, reconnecting &
polling. I too, would think that leaving the connections open would be
better, especially with only 5 servers.

Nevertheless, how could 'Address already in use' occur at a TCP client? I
can understand that the number of client sockets could easily run out on the
{*word*99}pier OS, eg W98, if there was a lot of open/close that used up sockets
faster than they could be recycled by winsock, (since it takes 2 mins
default for the wait timer to expire). But would this not give a different
error message? I am sure I have done this with a server test app that
created/opened/closed lots of clients & the error was not 10048.

Rgds,
Martin
 

Re:10048 WSAEADDRINUSE "Address already in use" Error

Thank you all so much for your quick responses.
My situation is a little odd. We manufacture gas flow measurement devices.
The devices are installed in the field on a gas line. The devices are
connected to the internet with several different technologies: CDPD, GPRS,
CDMA or with an IP to RS232 convertor. There may be several hundred of the
units which the host system must poll. Some of the units are solar powered
and only available during certain time windows. My test system on the bench
is a small scale system with 5 units with IP to RS232 convertors. I dont
think it is feasable to keep all connections open.
I know from watching the socket numbers that after I close a socket ,the
next time I connect, many times, the socket number is the same. This will
work for several open/close cycles. Then, for some reason, I will get the
10048 error. I guess the socket has not be properly freed up or something.
During the 2 minutes, what are the rules for reusing the socket?
Thanks,
Greg Dunn
"Martin James" <XXXX@XXXXX.COM>writes
Quote

"Gavin Watkinson" <XXXX@XXXXX.COM>writes
news:415ad138$XXXX@XXXXX.COM...
>You have one item listening on a port for data to come in, another item
>then tries to listen on the same port, causing the error.
>
>Have one client open for all the machines to talk to, dont keep opening
>and closing, then have some way to distinguish which machine is which.
>
>Gavin
>

Gregory's app is a little odd, with all that connecting, reconnecting &
polling. I too, would think that leaving the connections open would be
better, especially with only 5 servers.

Nevertheless, how could 'Address already in use' occur at a TCP client? I
can understand that the number of client sockets could easily run out on
the
{*word*99}pier OS, eg W98, if there was a lot of open/close that used up sockets
faster than they could be recycled by winsock, (since it takes 2 mins
default for the wait timer to expire). But would this not give a
different
error message? I am sure I have done this with a server test app that
created/opened/closed lots of clients & the error was not 10048.

Rgds,
Martin


 

Re:10048 WSAEADDRINUSE "Address already in use" Error

I am using the Delphi TTCPClient object from the Internet tab. I have also
used the TurboPower IPro TMultiIPClient with the same results. Do you think
I should give the Indy component a try as well. Would I gain anything?
I dont think the Delphi TTCPClient object has the bound ip/port.
Thanks,
Greg Dunn
"Gavin Watkinson" <XXXX@XXXXX.COM>writes
Quote
Saw the error msg and got it into my head it was a server - doh.

With the indy TcpClient are you setting the boundip and boundport
properties?

Gavin

>Gregory's app is a little odd, with all that connecting, reconnecting &
>polling. I too, would think that leaving the connections open would be
>better, especially with only 5 servers.
>
>Nevertheless, how could 'Address already in use' occur at a TCP client?
I
>can understand that the number of client sockets could easily run out on
the
>{*word*99}pier OS, eg W98, if there was a lot of open/close that used up
sockets
>faster than they could be recycled by winsock, (since it takes 2 mins
>default for the wait timer to expire). But would this not give a
different
>error message? I am sure I have done this with a server test app that
>created/opened/closed lots of clients & the error was not 10048.
>
>Rgds,
>Martin
 

Re:10048 WSAEADDRINUSE "Address already in use" Error

"Gregory A. Dunn" <XXXX@XXXXX.COM>writes
Quote
Thank you all so much for your quick responses.

My situation is a little odd. We manufacture gas flow measurement
devices.
The devices are installed in the field on a gas line. The devices are
connected to the internet with several different technologies: CDPD,
GPRS,
CDMA or with an IP to RS232 convertor. There may be several hundred of
the
units which the host system must poll. Some of the units are solar
powered
and only available during certain time windows. My test system on the
bench
is a small scale system with 5 units with IP to RS232 convertors. I dont
think it is feasable to keep all connections open.
I think that you probably can keep the connections open. With several
hundred connections, and given your h/w system, it is probably not necessary
to use several hundred threads for this. You could do - a few hundred
threads is not out of the question & would make comms coding much easier,
but it is probably not very efficient for your app/network with its slow
polling and server-specific time bands.
How about some timeWindow & server objects, like:
TonOffWindow=class
onTime:TdateTime;
offTime:TdateTime;
end;
EcommsState=(EcsDisconnected, EcsConnected,EcsPollSent,EcsBlahBlah);
EcommsCommand=(EccDeleted,EccWhatever),
TgasflowServer=class(TObject)
serverName:string;
hostName:string;
port:integer;
comms:TtcpClient;
onOffWindows:TobjectList;
command:EcommsCommand;
currentState:EcommsState;
nextActionTime:TdateTime;
function getNextEventTime:TdateTime;
end;
You could make a list of these objects, one for each server, ordered by the
time returned by 'getNextEventTime'. The object with the shortest NAT would
be at the front of the list. A timer could then time out this object. When
the timer fires, it is time to do something & you could queue the object to
some threads. A thread would get the object and, operating a state machine,
do whatever is required to perform the comms functionality, sending a poll,
trying to connect, whatever, and then calculate the time at which the next
action is required, (all this could be in the 'getNextEventTime' method), &
store it in the 'nextActionTime' field. The thread could then postMessage
the object back to the main thread, where it would be inserted in to the
time-list in the correct place, (possibly restarting the timer if it turned
out that its NAT was the shortest. This is not likely if there are a
reasonable number of servers, but you have to allow for it).
Some scheme like this would allow you to keep connections open to hundreds
of servers with a reasonable number of threads, avoiding needless socket
consumption.
A bit of twiddling with a TstringGrid or TlistView could allow you to watch
the progress of comms with the servers, add more servers, edit time windows
or delete servers quite easily in real time.
Rgds,
Martin
 

Re:10048 WSAEADDRINUSE "Address already in use" Error

Thanks for the advise. I will give it a shot.
Greg Dunn
"Martin James" <XXXX@XXXXX.COM>writes
Quote

"Gregory A. Dunn" <XXXX@XXXXX.COM>writes
news:XXXX@XXXXX.COM...
>Thank you all so much for your quick responses.
>
>My situation is a little odd. We manufacture gas flow measurement
devices.
>The devices are installed in the field on a gas line. The devices are
>connected to the internet with several different technologies: CDPD,
GPRS,
>CDMA or with an IP to RS232 convertor. There may be several hundred of
the
>units which the host system must poll. Some of the units are solar
powered
>and only available during certain time windows. My test system on the
bench
>is a small scale system with 5 units with IP to RS232 convertors. I
dont
>think it is feasable to keep all connections open.

I think that you probably can keep the connections open. With several
hundred connections, and given your h/w system, it is probably not
necessary
to use several hundred threads for this. You could do - a few hundred
threads is not out of the question & would make comms coding much easier,
but it is probably not very efficient for your app/network with its slow
polling and server-specific time bands.

How about some timeWindow & server objects, like:

TonOffWindow=class
onTime:TdateTime;
offTime:TdateTime;
end;

EcommsState=(EcsDisconnected, EcsConnected,EcsPollSent,EcsBlahBlah);
EcommsCommand=(EccDeleted,EccWhatever),

TgasflowServer=class(TObject)
serverName:string;
hostName:string;
port:integer;
comms:TtcpClient;
onOffWindows:TobjectList;
command:EcommsCommand;
currentState:EcommsState;
nextActionTime:TdateTime;
function getNextEventTime:TdateTime;
end;

You could make a list of these objects, one for each server, ordered by
the
time returned by 'getNextEventTime'. The object with the shortest NAT
would
be at the front of the list. A timer could then time out this object.
When
the timer fires, it is time to do something & you could queue the object to
some threads. A thread would get the object and, operating a state
machine,
do whatever is required to perform the comms functionality, sending a
poll,
trying to connect, whatever, and then calculate the time at which the next
action is required, (all this could be in the 'getNextEventTime' method),
&
store it in the 'nextActionTime' field. The thread could then postMessage
the object back to the main thread, where it would be inserted in to the
time-list in the correct place, (possibly restarting the timer if it
turned
out that its NAT was the shortest. This is not likely if there are a
reasonable number of servers, but you have to allow for it).

Some scheme like this would allow you to keep connections open to hundreds
of servers with a reasonable number of threads, avoiding needless socket
consumption.

A bit of twiddling with a TstringGrid or TlistView could allow you to
watch
the progress of comms with the servers, add more servers, edit time
windows
or delete servers quite easily in real time.

Rgds,
Martin