From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id 5F7E3BB9A for ; Wed, 9 Nov 2005 13:33:53 +0100 (CET) Received: from zproxy.gmail.com (zproxy.gmail.com [64.233.162.200]) by concorde.inria.fr (8.13.0/8.13.0) with ESMTP id jA9CXqN1002176 for ; Wed, 9 Nov 2005 13:33:53 +0100 Received: by zproxy.gmail.com with SMTP id x3so161162nzd for ; Wed, 09 Nov 2005 04:33:52 -0800 (PST) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition; b=JOf+ofSKTUy3DiRJGXFL+VSVczxgOt0lUo550nMwhQidAkHPbe9GFzLGBDDmLkV9T2MbSTL7+3BCZCgeuEBo3JcMB0ddVGC9ft93gxKhRXXRSKIEectRFgqGglNAlt+4hxnSs9lxBmPTegGuEcafRI6Cxi253fG7gjgrgNbfc0o= Received: by 10.65.225.15 with SMTP id c15mr722939qbr; Wed, 09 Nov 2005 04:33:52 -0800 (PST) Received: by 10.65.160.14 with HTTP; Wed, 9 Nov 2005 04:33:52 -0800 (PST) Message-ID: Date: Wed, 9 Nov 2005 13:33:52 +0100 From: Maurizio Colucci To: caml-list Subject: Error binding socket MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline X-Miltered: at concorde with ID 4371ECB0.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; rec:01 endline:01 endline:01 bug:01 sockets:01 howto:01 freeing:98 ...:98 ...:98 unix:01 unix:01 cleanup:01 int:01 match:02 binding:02 X-Spam-Checker-Version: SpamAssassin 3.0.3 (2005-04-27) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RCVD_BY_IP autolearn=disabled version=3.0.3 Hi there. For my free tennis game (http://freetennis.sf.net), I get an error binding the socket to a port. (Unix_error 50, "bind"). The error description is "address already in use". This error only happens the *second* time I start the program. It is as if the port had not been freed and were still in use. The system is GNU/Linux Ubuntu Breezy. However, if I wait about 1minute, or I start the program specifying a different port, the problem does not happen. It is as if Linux were freeing the port with a delay. At first glance, I thought I was not using Unix.close or Unix.socket correctly, but this does not seem to be the case. The code is freely available, however here is the relevant part of the code= : (* Here is the socket initialization phase, for both client and server: *) =09 let serverData =3D =09=09 let rec tryToConnectNTimes n ~soc ~inet_a ~port=3D =09=09 try =09=09=09 Unix.connect soc (Unix.ADDR_INET (inet_a, port) ) =09=09 with Unix.Unix_error _ -> =09=09=09 if n =3D 0 then =09=09=09 raise CouldNotConnectToServer =09=09=09 else =09=09=09 ( print_endline ( "The server is down. Retrying " ^ string_of_int (n-1) ^ " times."); =09=09=09=09Unix.sleep 1; =09=09=09=09tryToConnectNTimes (n-1) ~soc ~inet_a ~port ) =09=09 in =09=09 if !server then =09=09 let soc =3D Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in =09=09 ( =09=09=09 (try =09=09=09 Unix.bind soc (Unix.ADDR_INET (Unix.inet_addr_any, !port)) =09=09=09 with Unix.Unix_error (err, _, _) -> =09=09=09 (print_endline ("Error: " ^(Unix.error_message err) ^ ". Thi= s is a known bug. Please wait a few seconds or simply change the port number with the -port option"); =09=09=09 exit 0 )); =09=09=09 Unix.listen soc 5; =09=09=09 print_endline "waiting for client to connect..."; =09=09=09 let clientSocket, _ =3D Unix.accept soc in =09=09=09 Server ( (soc, clientSocket), Unix.in_channel_of_descr clientSocket, Unix.out_channel_of_descr clientSocket) =09=09 ) =09=09 else if 0 !=3D compare !client "" then =09=09 let soc =3D Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in =09=09 let inet_a =3D Unix.inet_addr_of_string !client in =09=09 print_endline "Connecting to server..."; =09=09 ( tryToConnectNTimes 60 ~soc ~inet_a ~port:!port; =09=09=09print_endline "Connected to server"; =09=09=09Client (soc, Unix.in_channel_of_descr soc, Unix.out_channel_of_de= scr soc) ) =09=09 else =09=09 NeitherServerNorClient =09 in (*... and here is the socket cleanup code *) =09 (match serverData with =09=09 (* the rule is to shutdown before you close, =09=09=09 but this is often automatic. see sockets =09=09=09 howto. =09=09 *) =09=09 | Server( (sock, clientSocket), inc, outc) -> =09=09=09 print_endline "Shutting down socket"; =09=09=09 Unix.shutdown clientSocket Unix.SHUTDOWN_ALL ; =09=09=09 Unix.shutdown sock Unix.SHUTDOWN_ALL ; =09=09=09 Unix.close clientSocket; =09=09=09 Unix.close sock; =09=09 | Client ( sock, inc, outc) -> =09=09=09 print_endline "Shutting down socket"; =09=09=09 Unix.shutdown sock Unix.SHUTDOWN_ALL ; =09=09=09 Unix.close sock; =09=09 | NeitherServerNorClient -> ()); One doubt I have is the following: in the server code, must I call close on sock or in clientSocket? If I am doing something wrong, could you please tell me. :-) Thank you Maurizio