Я пытаюсь написать http-клиент в OCaml:
module Connection = struct
let sock_fd =
let s_fd = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
Unix.setsockopt s_fd Unix.TCP_NODELAY true;
s_fd
let read_from_sock () =
let buffer = Bytes.create 512 in
let rec read_all request buffer =
let r = Unix.read sock_fd buffer 0 512 in
if r < 512 then request ^ buffer
else read_all (request ^ buffer) buffer in
read_all "" buffer
let write_to_sock str =
let len = String.length str in
let _ = Unix.write sock_fd str 0 len in ()
let make_request request serv_addr =
Unix.connect sock_fd serv_addr;
write_to_sock request
class connection address port =
object
val serv_addr = Unix.ADDR_INET (Unix.inet_addr_of_string address, port)
method get_response request =
let _ = make_request request serv_addr in
let rec wait_for_response () =
let response = read_from_sock () in
match String.length response with
| 0 -> wait_for_response ()
| _ -> Printf.printf "%s\n" response in
wait_for_response ();
Unix.shutdown sock_fd Unix.SHUTDOWN_ALL;
Unix.close sock_fd
end
let create address port = new connection address port
end
let connection = Connection.create "54.175.219.8" 80;;
connection#get_response "GET / HTTP/1.1\r\n"
Программа просто зависает до тех пор, пока не вылетит при сбросе соединения во время чтения. Самое интересное, что никаких других ошибок не выдается. Поскольку OCaml не возвращает ответ типа int, как C, я бы предположил, что если я сделал что-то неправильное при подключении или создании сокета, среда выполнения выдаст ошибку.
Если вы не знакомы с OCaml, я бы предположил (чрезвычайно грубый) псевдо-C эквивалент того, что я делаю (возможно, это поможет при отладке):
int sock_fd = socket(PF_INET, SOCK_STREAM);
setsockopt(sock_fd, TCP_NODELAY, 1);
serv_addr addr {"54.175.219.8", 80};
connect(sock_fd, &serv_addr);
write(sock_fd, "GET / HTTP/1.1\r\n");
char buffer[512];
while (buffer = read(sock_fd)) {
printf("%s\n", buffer);
}
shutdown(sock_fd, SHUTDOWN_ALL);
close(sock_fd);
Если это не помогает, игнорируйте это. Я просто решил обобщить в псевдокоде. Есть ли явные проблемы? (Помимо того, что не читается ответ int от socket/connect/write в C, потому что среда выполнения OCaml должна? позаботиться о выдаче здесь ошибок.)