|
Home > Archive > Unix Programming > January 2004 > UDP socket close problem
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
UDP socket close problem
|
|
| Mark Stevens 2004-01-23, 5:02 pm |
| Hi,
I have found a problem with reusing UDP ports which I can't
understand.
I have a UDP server application which lets the kernel allocate an
unused port by calling bind() with a sockaddr structure setup with
my_addr.sin_port = htons(0). This works fine and I always get an
unused port (lets say port X). When my server application terminates
I call close() on the socket descriptor and I check the return and
find no errors.
The problem comes about when I try to reuse port X. If another server
application binds to port X *before* any clients send datagrams to
that port, everything is fine and when clients start sending datagrams
they arrive safely. However, if the client sends data to port X
before the new server has bound to the port then when the server comes
to bind to the port it finds that it is already in use.
I don't observe this problem when the port is allocated by hand - it
only occurs when the port is allocated by the kernel. It seems
strange that the problem only appears when allowing the kernel to
allocate the port number and makes me think it is doing something else
behind the scenes which means that close() does not work as expected.
I'm using Linux RetHat 9, if that makes any difference.
Thanks for any suggestions.
Mark Stevens
The server code which allocates a free port is shown below:
int ListenSock;
struct sockaddr_in ServAddr;
struct sockaddr_in ResultAddr;
int ResultAddr_len;
if ((ListenSock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("Cannot create socket errno %d\n", errno);
perror( "");
exit(1);
}
/* bind the local address to the socket */
memset((void *)&ServAddr, 0, sizeof(ServAddr));
ServAddr.sin_family = AF_INET;
ServAddr.sin_addr.s_addr = htonl(INADDR_ANY);
ServAddr.sin_port = htons(0);
if (bind(ListenSock, (struct sockaddr *)&ServAddr, sizeof(ServAddr))
< 0)
{
printf("Failed to bind local address to socket errno %d\n",
errno);
perror( "");
exit(1);
}
ResultAddr_len = sizeof(ResultAddr);
getsockname(ListenSock, (struct sockaddr *)&ResultAddr,
&ResultAddr_len );
printf("Kernel allocated port: %u\n", ntohs(ResultAddr.sin_port));
if (close(ListenSock) != 0)
printf("Error closing socket descriptor.\n");
| |
| =?iso-8859-1?q?M=E5ns_Rullg=E5rd?= 2004-01-23, 5:02 pm |
| mas78910@hotmail.com (Mark Stevens) writes:
quote:
> I have found a problem with reusing UDP ports which I can't
> understand.
>
> I have a UDP server application which lets the kernel allocate an
> unused port by calling bind() with a sockaddr structure setup with
> my_addr.sin_port = htons(0). This works fine and I always get an
> unused port (lets say port X). When my server application terminates
> I call close() on the socket descriptor and I check the return and
> find no errors.
>
> The problem comes about when I try to reuse port X. If another server
> application binds to port X *before* any clients send datagrams to
> that port, everything is fine and when clients start sending datagrams
> they arrive safely. However, if the client sends data to port X
> before the new server has bound to the port then when the server comes
> to bind to the port it finds that it is already in use.
Try setting SO_REUSEADDR with setsockopt().
quote:
> I don't observe this problem when the port is allocated by hand - it
> only occurs when the port is allocated by the kernel. It seems
> strange that the problem only appears when allowing the kernel to
> allocate the port number and makes me think it is doing something else
> behind the scenes which means that close() does not work as expected.
>
> I'm using Linux RetHat 9, if that makes any difference.
Using redhat can sometimes make the best of code stop working.
--
Måns Rullgård
mru@kth.se
|
|
|
|
|