Browse thread
Error binding socket
- Maurizio Colucci
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: | 2005-11-09 (12:33) |
From: | Maurizio Colucci <maurizio.colucci@g...> |
Subject: | Error binding socket |
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: *) let serverData = let rec tryToConnectNTimes n ~soc ~inet_a ~port= try Unix.connect soc (Unix.ADDR_INET (inet_a, port) ) with Unix.Unix_error _ -> if n = 0 then raise CouldNotConnectToServer else ( print_endline ( "The server is down. Retrying " ^ string_of_int (n-1) ^ " times."); Unix.sleep 1; tryToConnectNTimes (n-1) ~soc ~inet_a ~port ) in if !server then let soc = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in ( (try Unix.bind soc (Unix.ADDR_INET (Unix.inet_addr_any, !port)) with Unix.Unix_error (err, _, _) -> (print_endline ("Error: " ^(Unix.error_message err) ^ ". This is a known bug. Please wait a few seconds or simply change the port number with the -port option"); exit 0 )); Unix.listen soc 5; print_endline "waiting for client to connect..."; let clientSocket, _ = Unix.accept soc in Server ( (soc, clientSocket), Unix.in_channel_of_descr clientSocket, Unix.out_channel_of_descr clientSocket) ) else if 0 != compare !client "" then let soc = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in let inet_a = Unix.inet_addr_of_string !client in print_endline "Connecting to server..."; ( tryToConnectNTimes 60 ~soc ~inet_a ~port:!port; print_endline "Connected to server"; Client (soc, Unix.in_channel_of_descr soc, Unix.out_channel_of_descr soc) ) else NeitherServerNorClient in (*... and here is the socket cleanup code *) (match serverData with (* the rule is to shutdown before you close, but this is often automatic. see sockets howto. *) | Server( (sock, clientSocket), inc, outc) -> print_endline "Shutting down socket"; Unix.shutdown clientSocket Unix.SHUTDOWN_ALL ; Unix.shutdown sock Unix.SHUTDOWN_ALL ; Unix.close clientSocket; Unix.close sock; | Client ( sock, inc, outc) -> print_endline "Shutting down socket"; Unix.shutdown sock Unix.SHUTDOWN_ALL ; Unix.close sock; | 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